JDK-4290946 : File.length() does not give current file size.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.2.2,1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1999-11-12
  • Updated: 2003-02-20
  • Resolved: 1999-11-12
Related Reports
Duplicate :  
Description

Name: skT88420			Date: 11/12/99


java version "1.2"
Classic VM (build JDK-1.2-V, native threads)

The java.io.File.length() method does not reflect the actual file size.
There is a distinct latency between writing to a file and
being able to get the resulting size.

The code below illustrates the problem, showing 20 lines ending in:

before write mod time: 942403265251 size=0 bytes written=720
 after write mod time: 942403265251 size=0 bytes written=800

If the Thread.sleep is uncommented, the size= correctly follows the bytes
written value.
My first thought was that this is due to some NTFS latency, but the Perl script
at
the end does the same thing but sees the correct file size after each syswrite.

Is there any more low-level flush or sync method I need to call to get
an accurate file size?

++++ start FileSize.java ++++

import java.io.*;
public class FileSize
{         
    final static String outFileName = "C:/temp/FileSize.tmp";
    final static byte[] data = "123456789 123456789 123456789 123456789
123456789 123456789 123456789 123456789\n".getBytes();
    final static int dataLen = data.length;
    static File outFile = null;
    static int bytesWritten = 0;
    
    static public void main(String args[])
    {
        outFile = new File(outFileName);
        FileOutputStream fo;
        outFile.delete();   // Remove any previous output file.
        try
        {
            fo = new FileOutputStream(outFile);
            for (int i=0; i < 10; i++)
            {
	            showFileInfo("before write ");
	            fo.write(data);
	            fo.flush();
	            // Thread.sleep(1000L);
	            bytesWritten += dataLen;
	            showFileInfo(" after write ");
            }
        } catch (Exception e)
        {
            System.out.println("Exception - " + e);
        }
    }
    static void showFileInfo(String prefix)
    {
        System.out.println(prefix + "mod time: " + outFile.lastModified()
	    + " size=" + outFile.length() + " bytes written="
	    + bytesWritten);
    }
}
++++   end FileSize.java ++++

++++ start fsize.pl ++++
#!perl -w

$OUT_FILE = "C:/temp/fsize.tmp";
open(OUT_FILE, ">$OUT_FILE") ||	die "Can't create $OUT_FILE - $!\n";
$DATA = "123456789 123456789 123456789 123456789 123456789 123456789 123456789
123456789\n";
$DATA_LEN = length($DATA);

$bytesWritten = 0;
for ($i=0; $i < 10; $i++)
{
	showFileInfo("before write ");
	my $bytes = syswrite OUT_FILE, $DATA, $DATA_LEN;
	print "Wrote $bytes, not $DATA_LEN!\n" if ($bytes != $DATA_LEN);
	$bytesWritten += $DATA_LEN + 1;	# +1 for additional "\r" added in
non-binmode
	showFileInfo(" after write ");
}
exit 0;
sub showFileInfo()
{
	my ($prefix) = @_;
	unless ( ($SIZE,undef,$MTIME) = (stat(OUT_FILE))[7..9] ) {
		warn ("Can't stat $OUT_FILE: $!\n");
		return 0;
	}
	print $prefix . "mod time: " . localtime($MTIME)
	. " size=" . $SIZE . " bytes written="
	. $bytesWritten . "\n";
}
++++   end fsize.pl ++++
(Review ID: 97766) 
======================================================================

Comments
WORK AROUND Name: skT88420 Date: 11/12/99 As shown above, a Thread.sleep(1000L) before asking for File.length() works (though the sleep time is presumably system load dependent). ====================================================================== If you get the filedescriptor object from the output stream and call sync(), the problem goes away. ###@###.### 2003-02-20
20-02-2003

EVALUATION Sometimes I/O is buffered to improve performance, so the changes are not immediately written out to the underlying device. michael.mccloskey@eng 1999-11-12 We are relying on the OS to report the file size to us. The buffering I mentioned above is not being done by us, but the operationg system. We could sync as part of the length call but that would cause a serious performance degradation. In the NIO API there is a force() call that will ensure that pending data is written out to disk. ###@###.### 2003-02-20
20-02-2003