1


I have to rename a file. I first tried File.renameTo(File), but this approach didn't work. The file wasn't opened anywhere else, nither in my program, nor in any other application. Since it sais in the documentation that this function is very System-Dependant, my next approach was to make a custom method. I tried using NIO, and resulted with the following method:

public boolean renameFile(File from, File to)
{
    Path fromPath = from.toPath();
    Path toPath = to.toPath();
    try {
        Files.copy(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING);
        Files.delete(fromPath);
    } catch (IOException ex) {
        return false;
    }
    return true;
}

The I discovered I couldn't do that, because when Files.delete(fromPath) is called, the file is still locked. I searched a bit and the found this question here on StackOverfolw. The solution there was to wait in a loop until the file wasn't locked anymore. I tried that, but found out, that the file was never unlocked until I exited the program. I did some more research and found this. What the accepted answer sais is, that this is a known Bug that Oracle can't fix. A comment suggested a workaround, avoiding use of NIO:

I would go with the Do-Not-Use-NIO workaround in this case.

I also tried that, and turned out with the following code:

private boolean renameFile(File from, File to)
{
    FileInputStream fromIn = null;
    FileOutputStream toOut = null;
    try
    {
        fromIn = new FileInputStream(from);
        toOut = new FileOutputStream(to);
        byte[] buffer = new byte[ 0xFFFF ];
        for(int len; (len = fromIn.read(buffer)) != -1;)
        {
            toOut.write(buffer);
        }
    }
    catch(IOException ex){
    return false;}
    finally
    {
        if(fromIn != null)
        {
            try {fromIn.close();} catch (IOException ex) {}
        }
        if(toOut != null)
        {
            try {toOut.close();} catch (IOException ex) {}
        }
    }

    from.delete();

    return true;
}

And again, as with my preceeding tries all files got copied to their new location, but from.delete(); failed, because they were locked - I couldn't even delete them in Explorer. I also tested if the streams just failed to close. But the streams closed correctly. I tried to find some more solutions, but I can't find any new ones. If anybody has any Ideas a code snipit with explanation would be appreciated. If you know another question with an answer not listed here, it is welcome to. Thanks for your help!

GeF

Community
  • 1
  • 1
GeF
  • 70
  • 6
  • Do you know that renameTo is actually a problem, ie. is it worse than copy and delete as delete is system dependant too. – Peter Lawrey Jul 29 '14 at 21:05
  • Do you open the file anywhere else? (not in your renameFile method) – user253751 Jul 29 '14 at 21:07
  • @PeterLawrey Yes, renameTo is a problem, witch is why I made my own function in the first place. I don't really understand what you are saying. – GeF Jul 29 '14 at 21:09
  • @GeF when you try to close the input and output stream, try to print out something if exception was caught. – nafas Jul 29 '14 at 21:10
  • @immibis No I didn't. Added it to the question. – GeF Jul 29 '14 at 21:11
  • You might find that rename and delete have a problem, since it does the same thing. – Peter Lawrey Jul 29 '14 at 21:11
  • @PeterLawrey Ok, so what should I use instead of delete to get rid of the file? – GeF Jul 29 '14 at 21:12
  • @nafas I did that, but didn't include it in the post to make the code as short as possible. It isn't because closing failed. – GeF Jul 29 '14 at 21:14
  • 1
    You will have to work out the cause of the problem rather than working around it. – Peter Lawrey Jul 29 '14 at 21:16
  • @GeF The file may be system dependent too. i.e. requires permission to be deleted. – nafas Jul 29 '14 at 21:17
  • @nafas Ok, but when I use `Files.delete(from.toPath());` a file system exception is thrown saying that the file is being used by another process and therefore can not be accessed. – GeF Jul 29 '14 at 21:23

0 Answers0