My Java application (which is quite a bit of code) does a lot of file operations. At one point in my application, I need to move a file from one location to another and for this I'm using the Files.move
method from JDK7.
When I try to do this, I get an error telling me that the file is in use. I know for a fact that it's some part of my code that is locking this resource.
How I force my Java application to release all locks prior to calling the function that moves/renames my file?
If this is not possible, is there an easy way to check which part of my code is locking the file? Trudging through my whole codebase to find unclosed file handles would be a nightmare considering the amount of code there is.
Thanks
In Java, a file lock can be obtained using FileChannel , which provides two methods — lock() and tryLock() — for this purpose. The lock() method acquires an exclusive lock on entire file, whereas the lock(long position, long size, boolean shared) method can be used to acquire a lock on the given region of a ile.
You can run from Java program the lsof Unix utility that tells you which process is using a file, then analyse its output. To run a program from Java code, use, for example, Runtime , Process , ProcessBuilder classes.
With the help of a debugger you can see all the instances of objects you have in memory (in Netbeans this would be Windows | Debugging | Loaded Classes, and then right click -> Show instances). You can then see all the FileInputStream
/FileOutputStream
instances you have, and identify those which point to the file you are trying to move. Once you have found a reference to your file, you can see who is still holding the reference.
If there is nobody holding a reference to the file, maybe the instance was discarded without calling close()
, and the file would be normally released only after a garbage collection. This makes the previous approach useless, since I think the debugger would automatically garbage collect those streams for you. Maybe you could put a conditional breakpoint inside the stream constructor, and tell it to stop only when the constructor parameter refers to your file.
If you can't find anything, as a last resort you could try to put a couple of System.gc()
calls before your move operation, and see if you have any improvement. Clearly this would be only quick-and-dirty fix, to give you some time until you find the actual problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With