eddy ed
eddy ed

Reputation: 967

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).

Upvotes: 3

Views: 3876

Answers (2)

Julien Gest
Julien Gest

Reputation: 1

Let's analyze the above observation...

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

The result is normal, because the file object has been produced via new File(foundFiles[i].getName()) but the method getName provides only the name of the file, WITHOUT its filepath !

By creating the file via new File(foundFiles[i].getParent() + File.separator + foundFiles[i].getName()), the results would then be :

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

Upvotes: 0

eddy ed
eddy ed

Reputation: 967

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.

Upvotes: 2

Related Questions