in reply to generating random filenames
While developing an upcoming perl monks utility release (xml_pimp) I went through a gamut ideas, in the midst of which, i thought about generating a temporary file.
I was messing with bunch of new things at the moment, some of which include the printf functions, regexes, inline pod ... ;)
None the less, here is what came out of it. Read it, test it, use it if you like.
++++What I went through to figure out how the generate the filename comes first, and my test script (that actually created and deleted files), comes after that .
#!/usr/bin/perl -w use strict; =head1 I MISUNDERSTOOD MY INPUT AND FUNCTION Apparently sprintf does not provide maximum length for number types, but only for strings. So in effect i was getting ints wih 8 or 9 digits before the . and the min length was 8, but you can't specify max length. Live and learn, and then make an ass out of yourself (almost) ;-^)~ I ended up making sure my input was an integer, and then treating it as a string with max and min length specified. Basically i feed it to sprintf twice =cut =head1 SPRINTF NOT PADDING CORRECTLY (original question) print sprintf(".crazy.%010u.temp",rand(time)),"\n"; print sprintf(".crazy.%08.8s.temp",rand(time)),"\n"; Its' fine if i use string, but it's supposed to be minimum length for + int but it doesn't pad with d (signed int), or with u (unsigned int). unless it's the length is 9 or greater. Is this flaw, or what? If i use 8, some numbers don't get padded. If i use 9 or greater, they do. I don't think this has to do with my specific version of perl, which is ActiveState 5.6(build 623) btw. Why, cause perldoc:pelrfunc says: Perl does its own sprintf formatting--it emulates the C function spri +ntf, but it doesn't use it (except for floating-point numbers, and even th +en only the standard modifiers are allowed). As a result, any non-standa +rd extensions in your local sprintf are not available from Perl. And since i'm not trying to represent a floating point number (i want + int), it should make no difference(not that it would anyway). Also, I do not wish to use %08s (for string), because sometimes a . s +neaks in, which is because rand(time) outputs a positive float that looks l +ike BTW - rand(time) yields results like: 598318636.889648 52034455.75 52445775.5732422 However, it hardly yields a value less than 8 digits digits bef +ore the decimal, but that's besides the point. BTW - srand is called automatically in my version of perl, so i don't call it explicitly cause it makes my results duplicates 1 +/3 of the time. =cut for(0..99) { print ' rand( ', rand(time),"\n"; } =head1 WHAT I TRIED =pod Here come the un-signed integer examples. sprintf(".crazy.%08u.temp" ,rand(time)) # min length 8, padd w/0 sprintf(".crazy.%08.8u.temp" ,rand(time)) # min length 8 or 8, padd w +/0 sprintf(".crazy.%010u.temp" ,rand(time)) # min length 10, padd w/0 sprintf(".crazy.%0.8u.temp" ,rand(time)) # not actually sure It's either padd with 0 w/min length of 8, or BTW - rand(time) yields results like: 598318636.889648 52445775.5732422 =head1 MY SOLUTION sprintf(".crazy.%08.8s.temp", sprintf("%u",rand(time)) ); Feed sprintf an unsigned int, and then feed that unsigned int to a sprintf with 0 for padding and a string of max length 8 and min length 8 (you gotta specify both to get a fixed width) or sprintf(".crazy.%08.8s.temp", int(rand(time)) ); It's a little bit faster, cause it uses int, but it's the same shit. =cut print &_titled_hr(' sprintf(".crazy.%010.10s.temp", sprintf("%u",rand( +time))) '); for(0..99) { print ' %010.10s(', sprintf(".crazy.%010.10s.temp", sprintf("%u",rand(time))), "\n"; } print &_titled_hr(' sprintf(".crazy.%010.10s.temp",rand(time)) '); for(0..99) { print ' %010.10s(', sprintf(".crazy.%010.10s.temp", int( rand(time) ) ), "\n"; } print &_titled_hr(' sprintf(".crazy.%08u.temp",rand(time)) '); for(0..99) { print ' %08u(', sprintf(".crazy.%08u.temp",rand(time)),"\n"; } print &_titled_hr(' sprintf(".crazy.%0.8u.temp",rand(time)) '); for(0..99) { print ' %0.8u(', sprintf(".crazy.%0.8u.temp",rand(time)),"\n"; } print &_titled_hr(' sprintf(".crazy.%08.8u.temp",rand(time)) '); for(0..99) { print ' %08.8u(', sprintf(".crazy.%08.8u.temp",rand(time)),"\n"; } print &_titled_hr(' sprintf(".crazy.%010u.temp",rand(time)) '); for(0..99) { print ' %010u(', sprintf(".crazy.%010u.temp",rand(time)),"\n"; } =pod Here come the signed integer examples. sprintf(".crazy.%08d.temp" , rand(time))) sprintf(".crazy.%0.8d.temp" , rand(time))) sprintf(".crazy.%08.8d.temp" , rand(time))) sprintf(".crazy.%010d.temp" , rand(time))) BTW - rand(time) always yields positive floats. =cut print &_titled_hr(' sprintf(".crazy.%08d.temp",rand(time)) '); for(0..99) { print ' %08d(', sprintf(".crazy.%08d.temp",rand(time)), "\n"; } print &_titled_hr(' sprintf(".crazy.%0.8d.temp",rand(time)) '); for(0..99) { print ' %0.8d(', sprintf(".crazy.%0.8d.temp",rand(time)), "\n"; } print &_titled_hr(' sprintf(".crazy.%08.8d.temp",rand(time)) '); for(0..99) { print ' %08.8d(', sprintf(".crazy.%08.8d.temp",rand(time)), "\n" +; } print &_titled_hr(' sprintf(".crazy.%010d.temp",rand(time)) '); for(0..99) { print ' %010d(', sprintf(".crazy.%010d.temp",rand(time)), "\n"; } exit; sub _titled_hr { my $string= join('', @_); my $oy = int (80 -(length $string) )/ 2; $oy -=2; return "\n ","-" x $oy, $string, "-" x $oy," \n"; }; ###################################################################### +######## ## END OF SCRIPT __END__
#!/usr/bin/perl -w use strict; use Compress::Zlib; my $userfile = '.crazyinsomniac.nodes.hashoaray.dat'; my $tempout = sprintf(".crazy.%010.10s.temp", int(rand(time)) ); for(0..10) { &testshit; &cleanup_file; } sub testshit { &compressor(); for(0..100) { $tempout = sprintf(".crazy.%010.10s.temp", int(rand(time)) ); &decompressor(); } } sub cleanup_file { unlink $tempout if -e $tempout; opendir(DIN,'.') or die "can't opendir . ($!)\n"; my @files = grep {/^.crazy.(\d){10}.temp$/} readdir(DIN); print "trying to delete(",scalar(@files),"):\n", join "\n", @files +,"\n"; print 'successfully deleted ',(unlink @files)," files \n"; } sub decompressor { my $x = inflateInit() or die "Cannot create a inflation stream\n"; my ($output, $status,$input); open(FIN , "<".$userfile.'.gz') or die "can't open $userfile($!)\n +"; open(FOUT, ">".$tempout) or die "can't open $tempout.gz($!)\n"; binmode FIN; binmode FOUT; while (read(FIN, $input, 4096)) { ($output, $status) = $x->inflate(\$input) ; if( ( $status == Z_OK ) or ( $status == Z_STREAM_END ) ) { print FOUT $output; } last if $status != Z_OK ; } close(FIN); close(FOUT); #unlink $tempout; # you will be deleted # since we don't wanna die before deleting this die "inflation failed\n" unless $status == Z_STREAM_END ; } sub compressor { open(FIN , "<".$userfile) or die "can't open $userfile($!)\n"; open(FOUT, ">".$userfile.'.gz') or die "can't open $userfile.gz($ +!)\n"; binmode FIN; binmode FOUT; my $deflation_stream = deflateInit() or die "Cannot create a defla +tion stream\n"; while (read(FIN, $_, 4096)) { my ($output, $status) = $deflation_stream->deflate($_); $status == Z_OK or die "deflation failed\n"; print FOUT $output ; } my ($output, $status) = $deflation_stream->flush(); $status == Z_OK or die "deflation failed\n"; print FOUT $output ; } sub sprinter { for(0..1000) { print sprintf(".crazyinsomniac.%010u.xml_pimp.tpl",rand(time)) +,"\n"; # print sprintf(".crazyinsomniac.%08.8s.xml_pimp.tpl",rand(tim +e)),"\n"; # its' fine if i use string, but it's supposed to be minimum l +ength for int # but it doesn't pad with d (signed int), but it does with u. # unless it's 9 or > (cause input is always 8 or less) # is this flaw, or what? # this is really fucked up. If i use 8, some strings don't ge +t padded # if i use 9 or greater, they do } }
___crazyinsomniac_______________________________________
Disclaimer: Don't blame. It came from inside the void
perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"
|
|---|