1

I just spent a lot of time tracking a bug where a file was not written and noticed that I delete the file after I created my FileOutputStream but before anything was written in it. I can understand that this is wrong, but why does it not throw an Exception to delete a file and then try to write on it?

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Test {

    public static void main(String[] args) throws FileNotFoundException, IOException
    {
        File test = new File("test.txt");
        try(OutputStream out = new FileOutputStream(test))
        {
            if(test.exists()) {test.delete();}
            out.write("Hello World".getBytes());
        }
    }
}

Is my Java installation broken? My java -version:

java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
Konrad Höffner
  • 11,100
  • 16
  • 60
  • 118

2 Answers2

0

It is not actually deleting the file. It is deleting the contents of the file. When you run the code and take out the out.write statement you will see the file is not actually deleted it is just deleting the text from the file. It can't delete the file completely because your FileOutputStream is referencing the file. If you take out FileOutputStream declaration then it will completely delete the file. Or if you close the FileOutputStream before you delete then it will completely delete the file.

Example:

        File test = new File("test.txt");
        try(OutputStream out = new FileOutputStream(test))
        {
            out.close();
            if(test.exists()) {System.out.println("test2");test.delete();}
            //out.write("Hello World2".getBytes());
        }
brso05
  • 13,142
  • 2
  • 21
  • 40
0

Deleting a file usually just involves removing its directory entry from the file system.

The File delete method returns true or false based on whether you're allowed to delete a file or not. This is different from the Files.delete method which throws an IOException if it can't delete a file. Since you're not checking this return value, you don't know if the file has been deleted or not.

This is important as different OSes have different rules on file deletion. For instance, Linux is perfectly happy to remove a directory entry for a file that is currently open. Hence you can still read/write a deleted file.

On the other hand, Windows enforces mandatory file locking and will simply refuse to delete the file.

Community
  • 1
  • 1
Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • But.. why isn't there an exception thrown when the file is removed? What happens to the output stream data when the file is removed? – ticktock May 18 '16 at 19:55