1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#!/usr/bin/perl use 5.020; use strict; use warnings; use Sereal; use Fcntl ':flock'; my $cachename = 'validator.cache'; my %validator; sub fetch_validator { if ( open my $CACHE, '<', $cachename ) { binmode $CACHE; my $data = <$CACHE>; close $CACHE or die; my $sereal = Sereal::Decoder->new(); if ( $sereal->looks_like_sereal($data) ) { my $VAR1 = $sereal->decode($data); %validator = %{$VAR1}; } else { warn "No SERAL data"; } return %validator; } } sub put_validator { if ( open my $CACHE, '>', $cachename ) { truncate $CACHE, 0; seek $CACHE, 0, 0; flock $CACHE, LOCK_EX; binmode $CACHE; my $sereal = Sereal::Encoder->new(); my $VAR1 = \%validator; my $data = $sereal->encode($VAR1); print $CACHE $data; close $CACHE or die; return %validator; } } use Digest::MD5 qw(md5_hex); for ( 1 .. 1_000 ) { my $d = $_; $validator{ 1000 + $d }{ time + rand $d } = md5_hex(time); put_validator(); fetch_validator(); }
2017-07-19T20:13:37 rostiDu setzt ein LOCK_EX und willst lesen.
QuoteEs wäre sinnvoll, nicht so klug von der Theorie zu reden sonder das auch mal zu testen!
1 2 3 4 5 6 7 8 9 10
my $CACHE = IO::File->new; $CACHE->open( $dateiname, O_RDWR|O_BINARY|O_TRUNC ) or die $!; # ggf. LOCK_EX # Schreiben $CACHE->print( $binary ); # Lesen read( $CACHE, my $binary, -s $CACHE);
2017-07-20T10:00:54 GwenDragonMein Fehler war: Ich habe vergessen vor dem Einlesen lokal $/ auf undef zu setzen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
use 5.020; use Fcntl; use strict; use warnings; my $file_name = 'C:\Windows\notepad.exe'; my $size = -s $file_name; my ($data_open, $data_sysopen); { open my $fh1, '<', $file_name; binmode $fh1; local $/; $data_open = <$fh1>; close $fh1; } { sysopen my $fh2, $file_name, O_RDONLY; binmode $fh2; read ($fh2, $data_sysopen, $size); } say "Groesse: ", $size; say "Laenge gleich: ", length($data_open), ' | ' , length($data_sysopen); say "Daten ", $data_open ne $data_sysopen ? 'ungleich' : 'gleich';
QuoteWarum kann man dann bloß sowas machen, wenn es unsinnig ist binmode und $/ zu nutzen:
2017-07-20T14:03:47 rostibinmode unter Win32 schiefgehen kann
2017-07-20T11:44:30 rostiDes Weiteren kann es unter Win32 passieren, dass die Datei bereits beim Öffnen gekürzt wird, weil Win32 die Datei als Textdatei betrachtet und bestimmte Bytesequenzen wie z.B. A0 am Dateiende einfach entfernt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
my $string = "TEST\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0"; if (! -s 'a.txt') { open my $fh, '>', 'a.txt'; binmode $fh; print $fh $string; close $fh; } open my $fh2, '<', 'a.txt'; binmode $fh2; my $data = <$fh2>; close $fh2; if (length($string) != length($data)) { die "STRANGE!"; }
1
2
3
4
5
6
T:\>del a.txt
T:\>perl a.pl
T:\>hd a.txt
/0 /1 /2 /3 /4 /5 /6 /7 /8 /9/ A /B /C /D /E /F 0123456789ABCDEF
0000 : 54 45 53 54 A0 A0 A0 A0 A0 A0 A0 A0 TEST........
GwenDragonCode (perl): (dl )1 2 3 4 5if ( open my $CACHE, '>', $cachename ) { truncate $CACHE, 0; seek $CACHE, 0, 0; flock $CACHE, LOCK_EX; binmode $CACHE;
https://stackoverflow.com/a/6388526Code: (dl )1
2
3
4
5
6use Fcntl qw( O_CREAT O_EXCL O_WRONLY O_EXLOCK );
$creat_flags = (O_CREAT | O_EXCL | O_WRONLY | O_EXLOCK );
sysopen(SOMEHANDLE, $somepath, $creat_flags, 0666)
|| die "$0: couldn't sysopen $somepath with flags $creat_flags: $!";
QuoteYour vendor has not defined Fcntl macro O_EXLOCK, used at lock.pl line 11