Skip to content
Advertisement

Looking for an explanation regarding file.delete() method in try catch block

Trying to make a simple ‘cut’ program to move files across folders. After it makes a copy it should delete the source file but it ignores the fileLocation.delete(); method in the try block. If I put it in the ‘finally’ block it works and also anywhere else in the program after it goes through copying the file but that makes no sense for it to work that way, even if something goes wrong the source will be deleted. My question is why does it ignore it, I was unable to find answers online. Thank you.

    File fileLocation = new File("C:\fileLocation\picture.png");
    File fileDestination = new File("C:\fileDestination\picture.png");

    try(FileInputStream input = new FileInputStream(fileLocation);
        FileOutputStream output = new FileOutputStream(fileDestination)) {

        byte[] buffer = new byte[1024];
        int length;

        while((length = input.read(buffer)) > 0) {
            output.write(buffer,0, length);
        }

        fileLocation.delete();

    } catch(IOException exc) {
        System.out.println(exc.getMessage());
    }

Advertisement

Answer

try(FileInputStream input = new FileInputStream(fileLocation);
    ... ) {
  // ..

  fileLocation.delete();
}

At this point, input is still open, so you can’t delete the file it refers to.

According to the definition of try-with-resources in the language spec, a finally block on a try-with-resources statement will be executed after the resource is closed. As such, putting the delete in the finally block means it can succeed.


Rather than putting it in the finally (which occurs whether or not an exception is thrown), you can split up the resources into two try-with-resources blocks, and delete once you’re done with input:

try (FileOutputStream output = ...) {
  try (FileInputStream input = new FileInputStream(fileLocation)) {
    // ..
  }

  // input is now closed.
  fileLocation.delete();
} catch(IOException exc) {
  System.out.println(exc.getMessage());
}

Now, fileLocation is only deleted when no IOException is thrown from any preceding statement in the output try-with-resources block (including the input try-with-resources block).

Or, if you want not to delete it until output is closed: move the IOException catch into a surrounding try/catch (not try-with-resources) block:

try {
  try (FileOutputStream output = ...;
       FileInputStream input = ...) {
    // ..
  }

  // input and output are now both closed.
  fileLocation.delete();
} catch(IOException exc) {
  System.out.println(exc.getMessage());
}

Of course, a better way to move a file would be to use the utility method to move files, e.g.

Files.move(fileLocation.toPath(), fileDestination.toPath(), CopyOption.REPLACE_EXISTING);
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement