Java I/O over an NFS mount

Melvin picture Melvin · Nov 24, 2009 · Viewed 10.9k times · Source

I have a bit of Java code that outputs an XML file to a NFS mounted filesystem. On another server that has the filesytem mounted as a Samba share, there is a process running that polls for new XML files every 30 seconds. If a new file is found, it is processed and then renamed as a backup file. 99% of the time, the files are written without an issue. However, every now and then the backup file contains a partially written file.

After some discussion with some other people, we guessed that the process running on the external server was interfering with the Java output stream when it read the file. They suggested first creating a file of type .temp which will then be renamed to .xml after the file write is complete. A common industry practice. After the change, the rename fails every time.

Some research turned up that Java file I/O is buggy when working with NFS mounted filesystems.

Help me Java gurus! How do I solve this problem?

Here is some relevant information:

  • My process is Java 1.6.0_16 running on Solaris 10
  • Mounted filesystem is a NAS
  • Server with polling process is Windows Server 2003 R2 Standard, Service Pack 2

Here is a sample of my code:

//Write the file
XMLOutputter serializer = new XMLOutputter(Format.getPrettyFormat());
FileOutputStream os = new FileOutputStream(outputDirectory + fileName + ".temp");
serializer.output(doc, os);//doc is a constructed xml document using JDOM
os.flush();
os.close();

//Rename the file
File oldFile = new File(outputDirectory + fileName + ".temp");
File newFile = new File(fileName + ".xml");
boolean success = oldFile.renameTo(newFile);
if (!success) {
    // File was not successfully renamed.
    throw new IOException("The file " + fileName + ".temp could not be renamed.");
}//if

Answer

jarnbjo picture jarnbjo · Nov 24, 2009

You probably have to specify the complete path in the new file name:

File newFile = new File(outputDirectory + fileName + ".xml");