binmode rueckgaengig machen
binmode rueckgaengig machen
am 28.08.2007 19:59:59 von Johannes
Hallo allerseits,
ich beschaffe mir mit
($fh, $filename) = tempfile();
aus File::Temp ein Filehandle $fh und einen Dateinamen $filename. Laut
Dokumentation von File::Temp wird die Datei im 'binary mode' geoeffnet.
Ich schreibe anschliessend in die Datei, schliesse sie und oeffne dann
einen Editor via
system($editor, $filename);
Wegen des 'binary mode' des Filehandles bewirken Schreiboperationen der
Form
print $fh "foobar\n";
dass auch unter Windows nur \n nicht die im Textmodus ueblichen \r\n als
Zeilentrennzeichen in der Datei landen.
Ich kann und will nicht ausschliessen, dass als Editor unter Windows
notepad.exe verwendet wird, der bekanntlich Schwierigkeiten mit
Unix-Zeilenenden hat. Deshalb moechte ich $fh im Textmodus verwenden.
Die Dokumentation zu File::Temp meint, man solle binmode() nutzen, um
den Modus von $filehandle zu korrigieren. Leider weiss ich nicht, wie
ich das anstellen soll.
Das Problem ist nicht wirklich schwerwiegend, denn es gibt diverse
Moeglichkeiten, es zu umgehen:
- bei print \r\n angeben oder mit binmode($fh, ":crlf") immer \r\n als
Zeilenende anhaengen und davon ausgehen, dass Unix-Editoren damit
klarkommen (notfalls auch betruebssystemabhaengig),
- $fh schliessen und $filename erneut im Textmodus oeffnen, was eine
race condition ermoeglicht, die allerdings bei meinem Programmablauf
ohnehin nicht ausgeschlossen wird.
Am sinnvollsten erschiene es mir allerdings, $fh wieder in den Textmodus
umzustellen. Wie geht das?
Gruss und Dank im voraus
Johannes
Re: binmode rueckgaengig machen
am 29.08.2007 19:29:31 von Guido Ostkamp
Johannes v. Löwis wrote:
> Am sinnvollsten erschiene es mir allerdings, $fh wieder in den Textmodus
> umzustellen. Wie geht das?
Du hast es ja selbst schon beschrieben:
Um unter Linux/Unix eine Datei im DOS/Windows Format zu beschreiben
benutzt Du binmode FH, ":crlf". Also z.B.
open FH, "> /tmp/outfile.txt" or die;
binmode FH, ":crlf";
print FH "Hello\n";
print FH "Hello\n";
close FH
Wenn Du die bspw. mit dem Editor 'vim' öffnest, solltest Du unten
in der Titelzeile (sofern aktiviert) sehen, daß er die automatisch als
[dos] formatige Datei erkennt. Unter Windows kannst Du also getrost
mit Notepad arbeiten. Voraussetzung ist natürlich, Du überträgst die
Datei original nach Windows und nicht etwa per FTP, der falsch
eingestellt evtl. selber eine Transformation durchführt.
Gruß
Guido
Re: binmode rueckgaengig machen
am 29.08.2007 20:15:44 von Wolf Behrenhoff
Guido Ostkamp schrieb:
> Johannes v. Löwis wrote:
>> Am sinnvollsten erschiene es mir allerdings, $fh wieder in den Textmodus
>> umzustellen. Wie geht das?
>
> Du hast es ja selbst schon beschrieben:
>
> Um unter Linux/Unix eine Datei im DOS/Windows Format zu beschreiben
> benutzt Du binmode FH, ":crlf". Also z.B.
Wenn ich Johannes richtig verstanden habe, möchte er ja genau das nicht!
Die Datei soll so geschrieben werden, wie es das Betriebssystem für
Textdateien vorgibt. D.h. unter Linux soll nur LF, unter Windows dagegen
CR+LF ausgegeben werden, also es soll das Standardverhalten von Perl
wiederhergestellt werden, wenn kein binmode verwendet wird.
Also vielleicht
binmode FH, ":crlf" if $^O eq "MSWin32";
aber das ist natürlich keine tolle Lösung.
Wolf
Re: binmode rueckgaengig machen
am 29.08.2007 21:15:39 von Johannes
Wolf Behrenhoff wrote:
> Die Datei soll so geschrieben werden, wie es das Betriebssystem für
> Textdateien vorgibt. D.h. unter Linux soll nur LF, unter Windows dagegen
> CR+LF ausgegeben werden, also es soll das Standardverhalten von Perl
> wiederhergestellt werden, wenn kein binmode verwendet wird.
Genau das wollte ich.
> Also vielleicht
>
> binmode FH, ":crlf" if $^O eq "MSWin32";
Sowas meinte ich mit meiner zweiten Problemumgehungsmoeglichkeit,
> aber das ist natürlich keine tolle Lösung.
Genauso sehe ich das auch.
Johannes
Re: binmode rueckgaengig machen
am 29.08.2007 22:34:28 von Guido Ostkamp
Wolf Behrenhoff wrote:
> Also vielleicht
>
> binmode FH, ":crlf" if $^O eq "MSWin32";
>
> aber das ist natürlich keine tolle Lösung.
Tja, dann entweder so oder er benutzt die geringfügig unsichere
Methode, besorgt sich via
use File::Temp qw/ :POSIX /;
$file = tmpnam();
einen Dateinamen und öffnet die Datei selber. Defaultmäßig ist sie ja
dann im Textmodus offen.
Gruß
Guido
Re: binmode rueckgaengig machen
am 02.09.2007 22:53:02 von w.koenig
On 28 Aug., 19:59, "Johannes v. Löwis" wrote:
>
> .....
>
> Am sinnvollsten erschiene es mir allerdings, $fh wieder in den Textmodus
> umzustellen. Wie geht das?
>
> Gruss und Dank im voraus
> Johannes
eventuell geht das mit:
my ( $fh, $filename ) =3D tempfile();
my @layers =3D PerlIO::get_layers($fh);
foreach (@layers) { binmode( $fh, ":pop" ); }
@layers =3D PerlIO::get_layers(STDOUT); # STDOUT sollte noch
Textmodus verwenden!
foreach (@layers) { binmode( $fh, ":$_" ); }
Siehe auch Doku zu PerlIO.
Winfried König