6

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)?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user1619114
  • 131
  • 1
  • 2
  • 9

6 Answers6

13

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!

christian.vogel
  • 2,117
  • 18
  • 22
  • I tried and it didn't worked. I guessed it was a bug yes, that what I read on other forum. Any other solution please ? You seems to know the topic =) – user1619114 Aug 23 '12 at 16:32
  • ok. dont forget that `test.txt` should exists under your project path :) – christian.vogel Aug 23 '12 at 17:22
  • Yes this example works for me. I don't know what is wrong with mine, maybe because I didn't flush, close, etc. in a finally ? When I do that it requires to put some throw or try catch in the finally, it's really weird – user1619114 Aug 23 '12 at 17:24
  • yes in the finally you have to catch exceptions as well. in my example i just throws the `Exception` so i do not have to handle them ^^ but its only for the example. in my opinion you should handle them. I added a piece of code that you can use. – christian.vogel Aug 23 '12 at 17:28
  • YEEEEEEEES ! It works OMG THANK YOU SO MUCH. I was trying to solve this problem ALL the night and thanks to you I got finally a solution !! Thank you very much !!!!! – user1619114 Aug 23 '12 at 17:37
  • I accidentally downvoted when I meant to upvote...please update your answer so I can change my vote (vote is locked). Thanks! – dberm22 Jun 18 '13 at 16:46
  • hi @dberm22 sorry haven't seen your comment, I updated my answer – christian.vogel Aug 22 '13 at 10:37
  • omG you're right...!!! that's very silly even until JDK 8 the bug is still exist? .... thanks for this solution anyway. – gumuruh Dec 01 '20 at 15:52
1

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.

Cornelia
  • 618
  • 1
  • 4
  • 11
0

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?

sciguy1121
  • 156
  • 8
0

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() );
Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • Hello, as you could see see, yes I used "deleteDirectory( path+"\\"+f[ j ] ); ", or maybe I misunderstood your proposal? – user1619114 Aug 23 '12 at 16:38
  • You need to download the library http://commons.apache.org/io/download_io.cgi & add the JARs to your classpath – Reimeus Aug 23 '12 at 16:53
  • Ok I did it but it's the same problem, i got the same exception : "java.io.IOException: Unable to delete file" – user1619114 Aug 23 '12 at 17:01
0

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.

tremoor
  • 1
  • 1
0

The problem may be in the first line: outFile = new FileOutputStream(dir+"\"+fileName);

  1. Not sure the new is required.
  2. Don't believe the directory should be included in the path. AFAIK the directory for FileOutputStream is defined as the app internal directory.

HTH

John L
  • 39
  • 6