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.
Related
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.
I am trying to create a temporary file and then rename it to a usable file. The temp file is getting created in %temp% but not getting renamed:-
static void writeFile() {
try {
File tempFile = File.createTempFile("TEMP_FAILED_MASTER", "");
PrintWriter pw = new PrintWriter(tempFile);
for (String record : new String[] {"a","b"}) {
pw.println(record);
}
pw.flush();
pw.close();
System.out.println(tempFile.getAbsolutePath());
File errFile = new File("C:/bar.txt");
tempFile.renameTo(errFile);
System.out.println(errFile.getAbsolutePath());
System.out.println("Check!");
} catch (Exception e) {
e.printStackTrace();
}
}
There are a few reasons why a rename can fail. The common ones are:
You don't have write permission for the source or destination directory.
The file you are renaming is open (on Windows)
You are attempting to rename across different file systems.
It can be difficult to diagnose these (and other) failure reasons if you are using File.renameTo because all you get is a boolean return value.
I recommend using Files.move instead. It can cope with moving files between file systems, and will throw an exception if the file cannot be renamed.
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
My program has a function that read/write file from resource. This function I have tested smoothly.
For example, I write something to file, restart and loading again, I can read that data again.
But after I export to jar file, I faced problems when write file. Here is my code to write file:
URL resourceUrl = getClass().getResource("/resource/data.sav");
File file = new File(resourceUrl.toURI());
FileOutputStream output = new FileOutputStream(file);
ObjectOutputStream writer = new ObjectOutputStream( output);
When this code run, I has notice error in Command Prompt:
So, My data cannot saved. (I know it because after I restarted app, nothing changed !!!)
Please help me solve this problem.
Thanks :)
You simply can't write files into a jar file this way. The URI you get from getResource() isn't a file:/// URI, and it can't be passed to java.io.File's constructor. The only way to write a zip file is by using the classes in java.util.zip that are designed for this purpose, and those classes are designed to let you write entire jar files, not stream data to a single file inside of one. In a real installation, the user may not even have permission to write to the jar file, anyway.
You're going to need to save your data into a real file on the file system, or possibly, if it's small enough, by using the preferences API.
You need to read/write file as an input stream to read from jar file.
public static String getValue(String key)
{
String _value = null;
try
{
InputStream loadedFile = ConfigReader.class.getClassLoader().getResourceAsStream(configFileName);
if(loadedFile == null) throw new Exception("Error: Could not load the file as a stream!");
props.load(loadedFile);
}
catch(Exception ex){
try {
System.out.println(ex.getMessage());
props.load(new FileInputStream(configFileName));
} catch (FileNotFoundException e) {
ExceptionWriter.LogException(e);
} catch (IOException e) {
ExceptionWriter.LogException(e);
}
}
_value = props.getProperty(key);
if(_value == null || _value.equals("")) System.out.println("Null value supplied for key: "+key);
return _value;
}
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.