http://www.perlmonks.org?node_id=256049


in reply to File::stat's size method returns negative values

Appears to me like a case of some freakish number conversion issue. Could you provide us with files table definition? What type is the size field? What Perl code do you use to insert the values?

I tend to think that there might be something happening between your code and mysql database that causes negative numbers. Could it be that the 'size' of the... ehem... size field isn't adequate and can't fit size values of some of the larger files?

update:

I'm not sure if you've stumbled over this newsgroup (comp.lang.perl.misc) post The author of the post refers to file sizes 'overflowing' the 32 bit number limit in Perl. From your post, this doesn't apear to be the deal, but I still found his workaround 'creative' ;).

By the way, I didn't mention this initially, but did you also verify whether the stat() method returned a negative value on any of the files? If all come out to be positives, then for sure look at the mysql<->perl link.

update 2: In reply to your update...

Being somewhat at a loss for any other 'good' suggestions, the alternative I see is to check if the negative size value follows any particular pattern. For example, do negative sized files appear in the same directory? shared drive/resource? Are their attributes any similar?

I'll test this on my win32 box shortly when I get home (I work on SOlaris at work ;)) and see if I could dig anything up.

_____________________
# Under Construction

Replies are listed 'Best First'.
Re: Re: File::stat's size method returns negative values
by djw (Vicar) on May 06, 2003 at 21:32 UTC
    I thought about that as well, but like I said, the size field in the table contains numbers larger than the ones I displayed. To be sure though, I altered the column to use BIGINT and the problem still occured (after I re-ran my program).

    Here is the insertion code:

    sub writeDB { # stuff ... $sth2 = $dbh->prepare( " insert into files ( client_id, path_id, file, size, ctime, mtime, atime ) values ( ?, ?, ?, ?, ?, ?, ? ) "); foreach my $path (keys %data) { my $pathInsert = qq`insert into path ( client_id, Path ) values ( ?, ? )`; $sth3 = $dbh->prepare($pathInsert); $sth3->execute($client_id, $path); $sth3->finish(); my $path_id = $sth3->{'mysql_insertid'}; foreach my $file (keys %{$data{$path}}) { my $size = $data{$path}{$file}{size}; my $ctime = $data{$path}{$file}{ctime}; my $atime = $data{$path}{$file}{atime}; my $mtime = $data{$path}{$file}{mtime}; $sth2->execute( $client_id, $path_id, $file, $size, $ctime, $atime, $mtime ); } } $sth2->finish(); $dbh->disconnect(); }
    Update: I did check to see if any of the files were negative before the perl->mysql code and they were at the time stat was performed (stat($_)).

    djw
      not an answer, but a means of reconciling - could you also do a qx(stat $_) and see how those values compare to perls built-in stat (or File::Stat 's over-ride)?
      #!/usr/bin/perl -w use strict; my $file = $0; # how BIG am I ? my $pstat_size = (stat($file))[7]; (my $qstat_size) = qx(stat $file) =~ m/Size: (-?\d+)/; print "$pstat_size, $qstat_size\n"; # not that big

      output is 175, 175
      I ran this against some 2G+ oracle dbf's, no problem

      (code assumes *nix or MS system with a visible stat exe somewhere)