Search code examples
javaunixjava-6file-rename

java file.renameTo() fails in unix


I have a java application that processes the contents of a file, and then I need to move it to another location.

This is how I read the file:

    String filePath = new String("foo.bar");
    String fileContents = new String("");
    char[] myBuffer = new char[chunkSize];
    int bytesRead = 0;
    BufferedReader in;
    try {
        FileReader fr = new FileReader(filePath);
        in = new BufferedReader(fr);
        try {
            while ((bytesRead = in.read(myBuffer,0,chunkSize)) != -1)
            {
                //System.out.println("Read " + bytesRead + " bytes. They were: " + new String(myBuffer));
                fileContents+= new String(myBuffer).substring(0, bytesRead);
            }
            // close the stream as I don't need it anymore. (If I don't close it, then java would hold the file open thus preventing the subsequent move of the file)
            in.close();
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return null;
    }

the file should be closed as I close both input stream and file reader.

Then after this I try to move the file to another directory using File.renameTo(newFileName); but this fails (under unix!, under windows it works fine)

Right after the move fails, I test whether I can create a file called newFileName and whether I can delete the original file. The new file gets to be created, while the original file fails to delete. Interestingly enough I can delete the original file from command line while the application is running (right after the failure).

Any idea why is that or any alternative?

More details: I am working under unix and I'm bound to use java 1.6 for legacy reasons (thus I can not revert to Files.move() which is supported starting from java 1.7).


Solution

  • I found what was the problem in my java application.

    Basically I extract a list of files from a directory using a custom FileFilter. This gives me an array File[] foundFiles. What I do afterwards is reading each file in a while loop using the snippet of code in the question. Right after the file is read for some reason I created a new File object using the i-th file from the array as parameter for the constructor

    File file = new File(foundFiles[i].getName()); // File to be moved
    

    and then I tried to rename this one.

    Now for some reason this works under windows while it doesn't under unix (the file is somehow locked I think by the foundFiles[i] object).

    In fact if I print the results of these lines

    System.out.println("I can read foundFiles[i]: " +foundFiles[i].canRead());// DEBUG
    System.out.println("I can write foundFiles[i]: " +foundFiles[i].canWrite());// DEBUG
    System.out.println("I can read file : " +file.canRead());// DEBUG
    System.out.println("I can write file : " +file.canWrite());// DEBUG
    

    I get

    I can read foundFiles[i]: True
    I can write foundFiles[i]: True
    I can read file: False
    I can write file: False
    

    It was simply enough to use renameTo() directly on the foundFiles[i] objects to make it work fine.

    Hope this helps, but I don't know why the first version would work under windows and not under unix.