koaps has asked for the wisdom of the Perl Monks concerning the following question:

Hola Monks,

I'm trying to fill a file until I hit a certain size, but for some reason it's not working for me.

I'm using this:
while ($tsize < $size) { print $fh "Some Something "; $tsize = $v->get_property('size'); }


Where $tsize is a variable containing the current file size and $size is my target size.
$v is a File::System::Object

I get the following results: If I set $tsize to 1, or anything less than 4110, the file gets filled to 4110 bytes.

If I set $tsize to 4110, the file will become 8205 bytes.

Am I missing something here?

Thanks, -C

Replies are listed 'Best First'.
Re: Filling a File with While
by moritz (Cardinal) on Nov 05, 2008 at 22:48 UTC
    It seems that File::System::Object returns the size that file occupies on disk, which is always a multiple of the block size.

    If you don't want that, simple use -s:

    while (-s $filename < $size) { print $fh "Some Something "; }

    Or maybe you have problems with buffering, try to turn on autoflush: $| = 1.

      I do want to know the size of the file on disk, how can I create a 1 gig file using the File::System::Object? I can see the blksize and blocks, so should I being doing something more like this:

      while ($v->get_property('block') < $bcount) { print $fh "Some Something "; }

      Where $bcount is the number of blocks I need to make up a 1 gig file? roughly 262,144 blocks right?

      Does the $fh have to be closed before I check the block size?

      while ($v->get_property('block') < $bcount) { $fh = $v->open('w'); print $fh "Some Something "; close $fh; }
Re: Filling a File with While
by graff (Chancellor) on Nov 06, 2008 at 00:16 UTC
    I'm trying to fill a file until I hit a certain size

    I'm wondering why you wouldn't just keep up a byte count of what gets written to the file:

    my $bytes_written = 0; my $bytes_wanted = 2**30; # or whatever my $data = "Something...\n"; # set output content here... while (1) { # $data = ...; # ... or here print $fh $data; $bytes_written += length( $data ); last if $bytes_written >= $bytes_wanted; }
    If you need to keep track in terms of block count, there would be a little more arithmetic involved (and correct background info about what the block size really is).

    As indicated in another reply, you might need to be careful about whether length() is counting bytes or wide (utf8) characters.

    UPDATED to fix stupid mistake in the "last if ..." line (needed to compare the right variable to $bytes_wanted).

      if you only need round about figures to stop the loop, you could even approximate the characters per line, and hence exit the loop based entirely on loop count.
      if you insist on lookup up file size, keep in mind that writing can be cached/buffered, and some system calls for filesystem info are cached unless a specific "full" system call is issued.
      the hardest line to type correctly is: stty erase ^H
Re: Filling a File with While
by GrandFather (Saint) on Nov 05, 2008 at 22:47 UTC

    There is far too little context for us to help except that 8205 is sorta close to twice 4110. Could it be that $tsize is in characters, $size is in bytes and the file is unicode?


    Perl reduces RSI - it saves typing
      The file is created using the File::System::Object, $tsize is from the File::System::Object get_property('size') and $size is a scalar number.

      $l and $v are File::System::Objects, in this case $l is a lookup and $v is hash value that stored the lookup object.
      my $size = 1000; my $tsize = $v->get_property('size'); my $f = $l->create("$file",'f');

      If that helps clear up anything