Java 7: Files.copy(), Files.move(), and Files.delete()
Before Java 7, performing basic file system operations like copying or moving a file was surprisingly difficult. Developers had to manually open input streams to read the source file, output streams to write to the destination, create byte buffers to transfer the data in chunks, and manage all the exceptions and resource closures. Moving a file often involved copying it and then manually deleting the original. This resulted in bloated utility classes that every project had to reinvent.
The NIO.2 API in Java 7 solved this by introducing straightforward, atomic, and highly optimized methods in the java.nio.file.Files utility class: Files.copy(), Files.move(), and Files.delete(). These methods delegate the heavy lifting to the underlying operating system whenever possible, making them much faster and more reliable than manual byte-transfer loops.
Both copy() and move() accept StandardCopyOption enum values to customize their behavior. By default, they will fail with an exception if the destination file already exists. However, by passing StandardCopyOption.REPLACE_EXISTING, you can instruct the JVM to overwrite the target. The move() method can also take ATOMIC_MOVE, which attempts to guarantee that the move happens as an indivisible file system operation, critical for concurrent applications.
For deletion, Files.delete(Path) removes a file or an empty directory, throwing a NoSuchFileException if it doesn't exist. Alternatively, Files.deleteIfExists(Path) is provided, which silently returns a boolean indicating success, saving developers from writing cumbersome if(Files.exists(path)) checks before deletion.
How it Works
Define Path objects for your source and destination. Call the respective Files methods. Provide StandardCopyOption arguments if you need to override default behaviors like existing file protection.
Java Example
Scenario 1: Copying a File
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.io.IOException;
public class FileOpsExample1 {
public static void main(String[] args) {
Path source = Paths.get("source.txt");
Path destination = Paths.get("backup.txt");
try {
// Create a dummy file for the example
Files.write(source, "Important Data".getBytes());
// Copy, replacing the backup if it already exists
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
System.out.println("File copied successfully to " + destination.getFileName());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
File copied successfully to backup.txt
Scenario 2: Moving/Renaming a File
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.io.IOException;
public class FileOpsExample2 {
public static void main(String[] args) {
Path oldFile = Paths.get("backup.txt"); // From previous example
Path newLocation = Paths.get("archive_backup.txt");
try {
// Moving effectively renames the file if it's in the same directory
Files.move(oldFile, newLocation, StandardCopyOption.REPLACE_EXISTING);
System.out.println("File moved/renamed successfully.");
System.out.println("Does old file exist? " + Files.exists(oldFile));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
File moved/renamed successfully.
Does old file exist? false
Scenario 3: Deleting Files Safely
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
public class FileOpsExample3 {
public static void main(String[] args) {
Path targetFile = Paths.get("archive_backup.txt"); // From previous example
Path phantomFile = Paths.get("does_not_exist.txt");
try {
// Using delete() - throws exception if missing
Files.delete(targetFile);
System.out.println("Target file deleted using delete().");
// Using deleteIfExists() - safe, no exception if missing
boolean deleted = Files.deleteIfExists(phantomFile);
System.out.println("Phantom file deleted? " + deleted);
} catch (IOException e) {
System.out.println("Deletion failed: " + e.getMessage());
}
// Clean up source.txt from Scenario 1
try { Files.deleteIfExists(Paths.get("source.txt")); } catch(Exception e){}
}
}
Output
Target file deleted using delete().
Phantom file deleted? false
Key Points
- Replaces complex byte-stream loops with single-line, OS-optimized methods.
StandardCopyOption.REPLACE_EXISTINGmust be used to overwrite existing destination files.ATOMIC_MOVEcan be used during a move to ensure file integrity in concurrent environments.deleteIfExists()is safer and cleaner than usingdelete()wrapped in an existence check.
Comments