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

hello, now I met a problem :
that's I got a negative value when I use -s and stat to get file size on a huge file ( 3.5G ).
So how should I do to get the correct one ?
Thanks very much!
  • Comment on How do I get correct file size for huge file under Win32?

Replies are listed 'Best First'.
Re: How do I get correct file size for huge file under Win32?
by BrowserUk (Patriarch) on Nov 25, 2008 at 09:44 UTC

    If you used print it will be displayed correctly:

    C:\test>dir huge.3.5GB 2008-11-25 09:29 3,758,096,387 huge.3.5GB 1 File(s) 3,758,096,387 bytes C:\test>perl -wle"print -s $ARGV[ 0 ]" huge.3.5GB 3758096387

    You'll only see the problem if you use printf with %d:

    C:\test>perl -wle"printf qq[%d\n], -s $ARGV[ 0 ]" huge.3.5GB -536870909

    And you can avoid that by using %f or %u instead:

    C:\test>perl -wle"printf qq[%.f\n], -s $ARGV[ 0 ]" huge.3.5GB 3758096387 C:\test>perl -wle"printf qq[%u\n], -s $ARGV[ 0 ]" huge.3.5GB 3758096387

    However, %u is limited to 2**32-1 (a limitation by design that %.f doesn't have):

    C:\test>dir huge.6.0GB 2008-11-25 09:40 6,442,450,947 huge.6.0GB 1 File(s) 6,442,450,947 bytes C:\test>perl -wle"printf qq[%u\n], -s $ARGV[ 0 ]" huge.6.0GB 4294967295 C:\test>perl -wle"printf qq[%.f\n], -s $ARGV[ 0 ]" huge.6.0GB 6442450947

    This "problem" is nothing to do with filesizes (or win32 per se), but rather that printf %d treats numbers as signed integers, so values between 2**31 and 2**32 are displayed as negative. They are held correctly internally.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      but I didn't use printf yet...
      I use print in your way.
Re: How do I get correct file size for huge file under Win32?
by moritz (Cardinal) on Nov 25, 2008 at 09:18 UTC

    Update: please ignore, read BrowserUk's explanation below instead. In my humble opinion that's a bug in perl, so please file a bug report for that.

    It sounds like a typical integer overflow.

    Maybe a workaround is to add 2**31 to negative sizes, but it's not a nice "solution" at all.

Re: How do I get correct file size for huge file under Win32?
by xiaoyafeng (Deacon) on Nov 25, 2008 at 12:19 UTC
    As far as I know, perl store file size value in a 32bit integer that means it's not possible to get the correct value if file size larger than 3.9G. But you can try Win32::DirSize


    I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

      As long as the perl in question is built with uselargefiles=define, (which means all AS perls and most others by default for at least the last 6+ years, probably longer), then perl quite happily, accurately and correctly deals with files up to at least 9e15 (~9,000 Terabytes).

      Also, I don't think it's even possible to get Win32::DirSize to give the size of a single file--unless it happened to be the only file in the directory--but in any case, it (and all it's conversion functions/methods) are totally unneccessary unless you have access to a filesystem that can store a single file > 9e15. (Is that even possible given current disk technology?)


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: How do I get correct file size for huge file under Win32?
by SadEmperor (Novice) on Nov 26, 2008 at 01:21 UTC
    I get different result under different OS and perl version.see table below.
    code : perl -e "print -s $ARGV[0]" bigfile.zip
    File size : 26.11.2008 08:53 3.482.452.674 bigfile.zip
    Environement Result
    Windows XP && Perl 5.6.1 -812514622
    Ubuntu* && Perl 5.8.8 3482452674

    * Ubuntu is running in VMware

    Since I can't install software on my office PC, so I don't test WindowsXP + Perl 5.8.8, and Ubuntu + perl 5.6.1