I have a directory M:\SOURCE from which I have listed and moved it's contents until it is empty
After that, I want to go ahead and delete it, I have tried (yes I also made sure it was empty):
sourceFile being "M:\SOURCE"
sourceFile.delete()
Files.delete(sourceFile.toPath());
FileUtils.deleteQuietly(sourceFile);
FileUtils.deleteDirectory(sourceFile);
FileUtils.forceDelete(sourceFile)
There are no exceptions being thrown by any of the other methods and .delete() returns true
HOWEVER, the directory still exists and when trying to access the folder I get the following message from windows:
When running process explorer I can see that java is using that resource (This only happens when I try to delete the source, and bear in mind that trying to delete source directory is the last thing my program does)
And just to make me freak out even more, once I stop my java virtual machine, THEN the folder magically disappears. So Java did got the instruction right, it's just that is not willing to delete it until it's terminated
Running System.gc() before deleting the directory also didn't help, and my working directory is not the one I'm trying to delete
You can get this problem when using Files NIO calls which list or return a Stream of directory contents before deleting the directory.
Using try with resources on any Stream of Path returned by Files NIO can help prevent this issue:
try(Stream<Path> stream = Files.list(directory)) {
// do any work on contents - move / delete
}
// delete directory after closing stream above
Related
I have created a class to perform commits to a Subversion repository using SVNKit. When I've completed the commits I want to destroy the temporary directory I was using as a working copy.
The way I'm creating the working copy directory is as follows:
Path svnWorkingCopyDirectory = Files
.createTempDirectory("svn-working-copy-directory-"
+ String.valueOf(System.currentTimeMillis()));
LOGGER.debug("Created SVN working copy directory: " + svnWorkingCopyDirectory);
svnWorkingCopyDirectory.toFile().deleteOnExit();
However, the directory does not get deleted on exit. Is there a way in SVNKit to mark the directory as no longer a working copy? Or another method to remove the directory?
File.deleteOnExit() works like File.delete() and Files.delete() in respect to the fact that if its argument denotes a directory, the directory must be empty to be removed which in your case probably it is not.
So if you want to delete this directory on exit you must register a shutdown hook and in that method you have to iterate recursively through the directory depth first to remove the files and then the empty directories.
Apache commons has a delete method you might use in a shutdown hook or whenever it is appropriate for you: https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/FileUtils.html#deleteDirectory(java.io.File)
I have a Java program (running under Java 6), that monitors a directory parses the name of found files and runs actions (including copying the file) according to meta data and file content then, depending on the success or failure of the process, moves the files to a OK or KO directory.
I run my program as a simple user.
I tried, for the test, to put files belonging to root in my monitored directory.
Furthermore, I gave them 000 permissions.
The program would find the files but fail on the copy of the file.
For the record, the actual copy is done on this model:
FileOutputStream fos = new FileOutputstrem(DestFile)
FileInputStream stream = new FileInputStream(File);
byte buffer[] = new byte[bufferSize];
int nbRead;
while (-1 != (nbRead = fin.read(buffer)))
fos.write(buffer, 0, nbRead);
So far, seeing the program fail is exactly what I expected, 000 permissions on a un-owned file, that cannot be read.
But what is strange is that my files were moved to the KO box.
The move is done with
File failedFileName = new File(KOdirectory, myFile.getName());
myFile.renameTo(failedFileName);
Should that work? (given they are onwed by root and with 000 permissions)?
They end up in the KO directory, still owned by root with 000 permissions.
When I add read permissions (so my files are 444 root-owned) and reinject them into the monitored folder, the whole process runs smoothly and files end up in the OK directory (still root-owned and 444 permissions).
How is it possible to move files on which one has only reading rights?
How does this reading, moving, deleting works depending on the OS? on the distro?
Maybe I should add I run this on Ubuntu whose awkward root user (it exists, but not completely) concept might be messing with this.
Moving and renaming files does nothing to the file contents; instead, it changes the directory entries. So you need write permission on the directory, not the file itself.
Try it: if you remove the write permission to the directory, and give write permission to the file, you won't be able to rename or move the file anymore.
There are commands like mv or rm that actually check the file permission, and ask for confirmation if you want to move or change them. But that's extra code in the command and does not come from the operating system itself.
This is the same on all linux/unix systems. Reading/changing a file's content checks the permissions on the file; changing the file name or moving it to a different directory checks the permissions on the directory(/ies). This does not depend on the distro, it's the same on all linux systems, as well as Solaris, AIX, HP/UX and what other commercial unixes there are.
Moving a file from one directory to another only requires modification of directory entries for the directories in question. This means that you need only write and search permissions to the directories. The permissions or the owner of the file being moved do not matter.
You can read more about this in the appropriate man pages, such as the page for rename(2) and path_resolution(7).
A file has permission and this determines if you can read, modify or execute this file.
A file exists in one or more directories and it is the permission of the directory, not the file, which determines if the directory can be listed, modified or used.
So when you move a file, you are changing the directory, not the file.
I have a simple Java app that is trying to copy a file across the WAN (from Ireland to NY).
I recently modified it to use FileUtils because the native Java file copy was too slow. I researched and found that because Fileutils uses NIO it is better. The file copy now works great but occasionally I need to copy very large files (> 200Mb) and the copy fails with the error:
java.io.IOException: Failed to copy full contents from...
I know the error means that the destination file size is not the same as the source, so initially I figured it was network problems. The process tries repeatedly to copy the file every couple of hours but it is never successful. However, when I copy the file manually through a Windows exploer then it works fine. This would seem to rule out the network...but I'm not really sure.
I have searched but could not find any posts with the exact same issue. Any help would be greatly appreciated.
Thanks!
Addition:
I am using this FileUtils method:
public static void copyFile(java.io.File srcFile, java.io.File destFile) throws java.io.IOException
So I found the issue to be on the destination folder. There is a polling process that is suppose to pick up the file after it gets copied. However, the file was getting moved prior to the copy being completed. This probably wouldn't happen on a windows drive because the file would be locked (i tested locally and i could not delete while file is copying). However, the destination folder is a mounted a celerra share. The unix process under the hood is what grabs the file...I guess it doesn't care if some windows process is still writing to it.
Thanks for your time medPhys-pl!
My java code is unable to delete files on the the system hard drive.
Whenever file.delete() function is called, it returns false.
Any ideas, why that might be happening?
File.delete() can fail to delete a file for many reasons including:
you don't have correct permissions to delete the file
the file represents a directory and the directory is not empty
the file is locked by another process, (or even by the same process in say an unclosed FileOutputStream)
the file doesn't exist
File.delete() can return false if you are trying to delete a directory that is not empty, or the named file simply doesn't exist at the time of the call.
(if there is a permission issue, a SecurityException is thrown)
I had the same issue in my code and found that the culprit was actually an unclosed FileInputStream. After closing that FIS my file deleted without any problems. I hope this helps someone.
The usual reasons are insufficient permissions (although normally that would throw an exception), trying to delete a non-existant file or trying to delete a non-empty directory. Are you totally sure that you have permissions to delete the file you are trying to delete?
Some process might be reading/writing the file, so that it is locked. Or then your process does not have permissions to delete the file. If the file is a directory, all files inside it must be deleted first before the directory can be deleted. And finally there is the situation that the file does not exist, so the delete method will return false.
Windows? Use the Process Explorer to search for all processes which keep a handle (lock) on the file (or if this is a directory on any file inside of it).
On Linux, use fuser.
You might be trying to delete any file exists in C: Drive and on that you might not have the permissions to do so. Try to put it inside any other drive than C: and then run your code. Hope it works for you. :)
Make sure the file is not currently is use:
For example i was trying to delete a file using
f2.delete()
But it was unable to do as i was using BufferReader,FileWriter,BufferWriter etc.Close all those and then try.
buffer.close()
writer.close()
For those who are having trouble to delete file using file.delete(), your problem is that the file is still open.
Close buffer reader
Close File Writer
and most important CLOSE THE FILE before file.delete(), otherwise it will not delete.
Enjoy.
I am working on a small basic GUI program that gets the files from my resources and gets the names of the files and places them in a combo box. for example i just have a file inside the same package called images and trying to get the files names. the way I get the file is by using the getResoure() like so
java.net.URL url = FileDemo.class.getResource("images");
but when I try to get the files inside the directory
File urlfile = new File(url.toString());
String[] files = urlfile.list();
the first line will convert the url to string and create a file object but when I try to get the list of files inside the directory it returns a null to the array of strings.
I broke down the code and used the debugger in netbeans found out, when it did the SecurityManager check it wouldn't pass.
My question is are the files inside the project protected or there is no way to access them using the list() and listFiles() or am i doing something wrong? Also I ran the same script on my schools computer which they have windows 7 the code above worked. But when i ran it on my mac and even 2 win xp machines it just didn't work? why is that ?
I hope this makes sense i am just stuck here still a new to java
Thanks in Advance.
The class to getResource(String) is returning a URL to images but there's no guarantee that this is a file URL (beginning "file:"). If your class is embedded within a jar file this certainly won't be the case, hence why it fails in some situations and not others.
If your intention here is to actually make a portion of a file system visible to the user then I'd recommend avoiding getResource altogether, which is typically more useful when your application wishes to locate and load resources such as icons or config files.
Instead, you could use JFileChooser, which is a rich Swing component for navigating the file system and selecting files.