This is currently what I have to delete the file but it's not working. I thought it may be permission problems or something but it wasn't. The file that I am testing with is empty and exists, so not sure why it doesn't delete it.
UserInput.prompt("Enter name of file to delete");
String name = UserInput.readString();
File file = new File("\\Files\\" + name + ".txt");
file.delete();
Any help would be GREATLY appreciated!
I now have:
File file = new File(catName + ".txt");
String path = file.getCanonicalPath();
File filePath = new File(path);
filePath.delete();
To try and find the correct path at run time so that if the program is transferred to a different computer it will still find the file.
The problem could also be due to any output streams that you have forgotten to close. In my case I was working with the file before the file being deleted. However at one place in the file operations, I had forgotten to close an output stream that I used to write to the file that was attempted to delete later.
Be sure to find out your current working directory, and write your filepath relative to it.
This code:
File here = new File(".");
System.out.println(here.getAbsolutePath());
... will print out that directory.
Also, unrelated to your question, try to use File.separator to remain OS-independent. Backslashes work only on Windows.
I got the same problem! then realized that my directory was not empty. I found the solution in another thread: not able to delete the directory through Java
/**
* Force deletion of directory
* #param path
* #return
*/
static public boolean deleteDirectory(File path) {
if (path.exists()) {
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
return (path.delete());
}
Try closing all the FileOutputStream/FileInputStream you've opened earlier in other methods ,then try deleting ,worked like a charm.
I suspect that the problem is that the path is incorrect. Try this:
UserInput.prompt("Enter name of file to delete");
String name = UserInput.readString();
File file = new File("\\Files\\" + name + ".txt");
if (file.exists()) {
file.delete();
} else {
System.err.println(
"I cannot find '" + file + "' ('" + file.getAbsolutePath() + "')");
}
If you want to delete file first close all the connections and streams.
after that delete the file.
In my case it was the close() that was not executing due to unhandled exception.
void method() throws Exception {
FileInputStream fis = new FileInputStream(fileName);
parse(fis);
fis.close();
}
Assume exception is being thrown on the parse(), which is not handled in this method and therefore the file is not closed, down the road, the file is being deleted, and that delete statement fails, and do not delete.
So, instead I had the code like this, then it worked...
try {
parse(fis);
}
catch (Exception ex) {
fis.close();
throw ex;
}
so basic Java, which sometimes we overlook.
As other answers indicate, on Windows you cannot delete a file that is open. However one other thing that can stop a file from being deleted on Windows is if it is is mmap'd to a MappedByteBuffer (or DirectByteBuffer) -- if so, the file cannot be deleted until the byte buffer is garbage collected. There is some relatively safe code for forcibly closing (cleaning) a DirectByteBuffer before it is garbage collected here: https://github.com/classgraph/classgraph/blob/master/src/main/java/nonapi/io/github/classgraph/utils/FileUtils.java#L606 After cleaning the ByteBuffer, you can delete the file. However, make sure you never use the ByteBuffer again after cleaning it, or the JVM will crash.
Related
I have this piece of code in my project:
String readFile() {
String pathname = saveDirectory + fileName + ".txt";
String content = "";
File f = new File(pathname);
if (f.exists() && !f.isDirectory()) {
try {
content = new String(Files.readAllBytes(Paths.get(pathname)));
}
catch (IOException e) { }
}
return content;
}
There are no errors, the aplication runs just right, but the content variable never has any text in it and I'm sure that the txt file has text in it!
I've already tried different ways to read the text file (with BufferedReader, Scanner, FileInputStream and FileReader) but none of them worked.
Ps. I'm almost sure that the problem isn't in the pathname variable since I've tried to open the file via code (with Runtime) and it opened the right file normally.
Ok, I tried adding the e.printStackTrace(); but there is still no errors, and it's not missing a / between the directory and the fileName, i've already added in the \\ in the directory variable.
Could you be forgetting the / between the directory and the file name? Print the content of pathname and see.
Or better: debug your code and see what happens.
It looks like you're opening the file once (File f = new File(pathname);), then trying to read it without using the file object you created. You're probably getting an IOException because Files.readAllBytes(Paths.get(pathname)) can't open the file while f has it open.
I'll post my code first:
private void validateXml(String xml) throws BadSyntaxException{
File xmlFile = new File(xml);
try {
JaxbCommon.unmarshalFile(xml, Gen.class);
} catch (JAXBException jxe) {
logger.error("JAXBException loading " + xml);
String xmlPath = xmlFile.getAbsolutePath();
System.out.println(xmlFile.delete()); // prints false, meaning cannot be deleted
xmlFile.delete();
throw new BadSyntaxException(xmlPath + "/package.xml");
} catch (FileNotFoundException fne) {
logger.error("FileNotFoundException loading " + xml + " not found");
fne.printStackTrace();
}
}
You can see in my comment where I print that the file cannot be deleted. Files can't be deleted from a try/catch? So, if there is a file with bad xml syntax, I want to delete the file in the catch.
EDIT: I can delete the file when I use delete() from outside of this function. I am on Windows.
Make sure that this method invocation JaxbCommon.unmarshalFile(xml, Gen.class); closes any stream when the exception occurs. If the stream that was reading the file is left opened then you cannot delete it.
The problem is unrelated to the try/catch. Do you have permissions to delete the file?
If you are using Java 7 you can use the Files.delete(Path) which I think will actually throw an IOException with the reason why you can't delete the file.
There is no general restriction regarding the use of java.io.File.delete() on try/catch blocks.
The behavior of many java.io.File methods can depend on platform/enviroment that the application is running. It is because they can need to access file system resources.
For example, the following code returns false on Windows 7 and true on Ubuntu 12.04:
public static void main(String[] args) throws Exception {
File fileToBeDeleted = new File("test.txt");
// just creates a simple file on the file system
PrintWriter fout = new PrintWriter(fileToBeDeleted);
fout.println("Hello");
fout.close();
// opens the created file and does not close it
BufferedReader fin = new BufferedReader(new FileReader(fileToBeDeleted));
fin.read();
// try to delete the file
System.out.println(fileToBeDeleted.delete());
fin.close();
}
So, the real problem can depend on several factors. However, it is not related to the code residing on a try/catch block.
Maybe, the resource that you is trying to delete was opened and not closed or locked by another process.
I am currently facing some problem with a FileOutputStream in my Java code.
Actually I am using a FileOutputStream for creating a file, but then once the file is created there is no way for deleting it. As far as I could understand, this may come from the fact that the FileOutputstream is not closed.
On below my summarized code :
outFile = new FileOutputStream(dir+"\\"+fileName);
outFile.write("Test");
outFile.flush();
outFile.close();
outFile = null;
System.gc();
Then there is no way to delete the file, even "by hand". When my program is launched, I can't delete it on windows by a simple del. I also tried to remove content of the folder dir and it didn't worked neither, using this code :
static public void delDir( String place )
{
File path = new File( place );
System.out.println(path.exists());//return true
if( path.exists() )
{
File[] f = path.listFiles();
for( int j = 0 ; j < f.length ; j++ )
{
if( f[ j ].isDirectory() )
{
deleteDirectory( path+"\\"+f[ j ] );
}
f[ j ].delete();
}
}
}
So my question is :
How to close this file for a next delete (or how to delete it properly if we can't close it)?
It is a bug in Java. Yes it it rarely but they exists ;) Could you add after outFile.close()
outFile = null;
System.gc();
And then try to delete it. There are more possiblity if this is not working. Let me know.
UPDATE
For me it works:
public class FileDeleteExample {
public static void main(String[] args) throws Exception {
File f = new File("test.txt");
FileOutputStream outFile = null;
try {
outFile = new FileOutputStream(f);
outFile.write("Test".getBytes());
} finally {
outFile.flush();
outFile.close();
outFile = null;
System.gc();
}
f.delete();
}
}
UPDATE
I tried it with the example Sumit Singh mentioned by deleting the lines outFile=null; System.gc; and this works as well for me. So there should'nt be a problem with the FileOutputStream. Could you try the little example above and say whether it works or not?
UPDATE
void closeQuietly(FileOutputStream out) {
try { out.flush(); out.close(); } catch(Exception e) {}
}
Now just call the method in the finally block!
I had the same problem, the delete() method returned false for my File.
In my case, somewhere in between creating the file, writing to its FileOutputStream and deleting the file, i was using a FileInputStream and forgot to call close() for it.
So, maybe somewhere in your code you attached another stream to this file, and left it open.
Before finding the real source of the problem, i used a simle hack to temporarily fix this:
FileOutputStream fos = new FileOutputStream(myFile);
fos.close();
myFile.delete();
Right before calling delete on my File, i created another FileOutputStream over it and then just called close().
This unlocks all previuous locks on this file and lets you call delete().
Still it is not a good practice to do this. You should find out who uses your file and solve it the right way.
Well, the way to close a file output and input streams is:
name.close()
and your deletion code looks fine. My recommendation would be to use FileIO instead of FileOutputStream, unless you're using FileOutputStream for a good reason. Can you delete the file once the program closes?
Better to use FileUtils.deleteDirectory from Apache Commons IO. Overcomes the Java delete bug, reduces amount of code used and most of all, it works.
Instead of calling
delDir(place);
just call
FileUtils.deleteDirectory(new File(place));
Update:
In your delDir method, you call:
deleteDirectory(new File(path + "\\" + f[j]));
but the result of
File[] f = path.listFiles();
will already include the path in the file, so you can just use:
deleteDirectory( f[j].getPath() );
Not really related but:
This solution of the closing of a file helped me with another problem. When run a programme from java 6 the new process was suspended until I closed my application (in java 7 it was ok).
The solution based on this answer helped:
String[] com = new String[]{javaRun, arg1, arg2, arg3, arg4};
Process proc = Runtime.getRuntime().exec(com, null, dir);
proc = null;
System.gc();
This works with java 6. Thanks for inspiration.
The problem may be in the first line:
outFile = new FileOutputStream(dir+"\"+fileName);
Not sure the new is required.
Don't believe the directory should be included in the path. AFAIK the directory for FileOutputStream is defined as the app internal directory.
HTH
Can anyone please tell me how to delete a file in a directory after being opened and loaded on to a database?
Here is my code:
public static void main(String[] args) throws SQLException{
int Count= 0;
File directory = new File("C://Documents and Settings//welcome//My Documents//Bluetooth Exchange Folder");
directory.deleteOnExit();
File files[] = directory.listFiles();
for(int index = 0; index < files.length; index++){
try {
FileReader inp = new FileReader (files[index]);
BufferedReader buf = new BufferedReader(inp);
String strLine;
try {
while ((strLine = buf.readLine()) != null)
{
System.out.println(strLine);
String[] dbColumnValues = strLine.split("%");
Connect.DoInsertIntoDB(Long.parseLong(dbColumnValues[0]),dbColumnValues[1],dbColumnValues[2], dbColumnValues[3]);
Count++;
System.out.println(Count + " Row(s) are inserted into the Database");
GenHTML.gen();
}
}
But the files are not deleted in the directory.
Please can anyone correct the mistake in my code?
[Currently, I am testing with 3 files in the directory. After each file gets loaded to the datbase, I want each files to get deleted from the directory.]
Thanks in advance!
It is better to be explicit in your code.
File files[] = directory.listFiles();
for(int index = 0; index < files.length; index++){
{
// Process files[index]
// ...
boolean wasDeleted = files[index].delete();
if (!wasDeleted)
{
// Deal with error
}
}
Also, you need to close your file handles when you are done with them
FileReader inp = new FileReader (files[index]);
try
{
// ...
}
finally
{
inp.close();
}
The File.delete() and File.deleteOnExit() methods will only delete a directory if it's empty. You'll have to delete the files from the directory as you process them (and make sure there are no subdirectories). Alternatively you can use FileUtils.deleteDirectory() from Apache Commons IO at the end of your processing.
The double slashes seems suspect. Either use a single backslash, which you need to quote as \\, or use a single slash /.
Also, you could try using delete() when then method returns instead of deleteOnExit().
According to the API:
Requests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates.
In your code, however, you are treating that function as if it immediately deletes the directory.
You can't delete a directory, unless it's empty. If the directory is not empty, it is necessary to first recursively delete all files and subdirectories in the directory.
So directory.deleteOnExit() won't work in your case.
More, I suggest you to explicitly delete the files, not using deleteOnExit(). It is a dumb function that won't delete the file on exit if all the input/output streams related to the file are not closed. Always close the streams and explicitly delete the files, then the directory.
Maybe what you need to do is to use the dispose() method for the component that opens the file. What could possibly be the situation is that the file is still seen as opened and locked by a component that it had been opened in, so you have to ensure you use the dispose() method to solve that problem.
This is currently what I have to delete the file but it's not working. I thought it may be permission problems or something but it wasn't. The file that I am testing with is empty and exists, so not sure why it doesn't delete it.
UserInput.prompt("Enter name of file to delete");
String name = UserInput.readString();
File file = new File("\\Files\\" + name + ".txt");
file.delete();
Any help would be GREATLY appreciated!
I now have:
File file = new File(catName + ".txt");
String path = file.getCanonicalPath();
File filePath = new File(path);
filePath.delete();
To try and find the correct path at run time so that if the program is transferred to a different computer it will still find the file.
The problem could also be due to any output streams that you have forgotten to close. In my case I was working with the file before the file being deleted. However at one place in the file operations, I had forgotten to close an output stream that I used to write to the file that was attempted to delete later.
Be sure to find out your current working directory, and write your filepath relative to it.
This code:
File here = new File(".");
System.out.println(here.getAbsolutePath());
... will print out that directory.
Also, unrelated to your question, try to use File.separator to remain OS-independent. Backslashes work only on Windows.
I got the same problem! then realized that my directory was not empty. I found the solution in another thread: not able to delete the directory through Java
/**
* Force deletion of directory
* #param path
* #return
*/
static public boolean deleteDirectory(File path) {
if (path.exists()) {
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
return (path.delete());
}
Try closing all the FileOutputStream/FileInputStream you've opened earlier in other methods ,then try deleting ,worked like a charm.
I suspect that the problem is that the path is incorrect. Try this:
UserInput.prompt("Enter name of file to delete");
String name = UserInput.readString();
File file = new File("\\Files\\" + name + ".txt");
if (file.exists()) {
file.delete();
} else {
System.err.println(
"I cannot find '" + file + "' ('" + file.getAbsolutePath() + "')");
}
If you want to delete file first close all the connections and streams.
after that delete the file.
In my case it was the close() that was not executing due to unhandled exception.
void method() throws Exception {
FileInputStream fis = new FileInputStream(fileName);
parse(fis);
fis.close();
}
Assume exception is being thrown on the parse(), which is not handled in this method and therefore the file is not closed, down the road, the file is being deleted, and that delete statement fails, and do not delete.
So, instead I had the code like this, then it worked...
try {
parse(fis);
}
catch (Exception ex) {
fis.close();
throw ex;
}
so basic Java, which sometimes we overlook.
As other answers indicate, on Windows you cannot delete a file that is open. However one other thing that can stop a file from being deleted on Windows is if it is is mmap'd to a MappedByteBuffer (or DirectByteBuffer) -- if so, the file cannot be deleted until the byte buffer is garbage collected. There is some relatively safe code for forcibly closing (cleaning) a DirectByteBuffer before it is garbage collected here: https://github.com/classgraph/classgraph/blob/master/src/main/java/nonapi/io/github/classgraph/utils/FileUtils.java#L606 After cleaning the ByteBuffer, you can delete the file. However, make sure you never use the ByteBuffer again after cleaning it, or the JVM will crash.