To copy a file in Java, the most recommended and modern approach is to use the java.nio.file.Files.copy()
method, which provides efficient and robust file operations as part of the NIO.2 API introduced in Java 7.
1. Using java.nio.file.Files.copy()
(Recommended)
The Files
class, located in the java.nio.file
package, provides several static methods for interacting with the file system. The copy()
method is designed for straightforward and performant file duplication.
Key Features of Files.copy()
:
- Path-based: It operates on
Path
objects, which are an improved way to represent file system paths compared to the olderFile
class. - Flexibility with
CopyOption
s: You can customize the copy behavior usingStandardCopyOption
enum values. - Efficient: Handles buffering internally, making it generally more efficient than manual stream copying.
- Error Handling: Throws
IOException
for file system errors, which should be handled.
The primary method signature for copying a file from one path to another is:
Path copy(Path source, Path target, CopyOption... options)
By default, the copy operation fails if the target file already exists, throwing a FileAlreadyExistsException
. To overwrite an existing target file, you must specify the StandardCopyOption.REPLACE_EXISTING
option.
Common StandardCopyOption
s:
Option | Description |
---|---|
REPLACE_EXISTING |
If the target file exists, it is replaced by the source file. If not specified, and the target file exists, the copy operation fails with a FileAlreadyExistsException . |
COPY_ATTRIBUTES |
Attempts to copy the file attributes (e.g., last modified time, permissions) of the source file to the target file. The exact attributes copied depend on the file system. |
NOFOLLOW_LINKS |
If the source file is a symbolic link, the link itself (not its target) is copied. If not specified, and the source is a symbolic link, the target of the link is copied. |
Practical Examples:
To use Files.copy()
, you'll typically need to import java.nio.file.Files
, java.nio.file.Path
, java.nio.file.Paths
, and potentially java.nio.file.StandardCopyOption
. Always wrap file operations in a try-catch
block to handle potential IOException
s.
a. Basic File Copy (Fails if Target Exists)
This example attempts to copy source.txt
to target.txt
. If target.txt
already exists, a FileAlreadyExistsException
will be thrown.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.FileAlreadyExistsException;
public class FileCopyBasic {
public static void main(String[] args) {
Path sourcePath = Paths.get("data/source.txt"); // Replace with your source file path
Path targetPath = Paths.get("data/target.txt"); // Replace with your target file path
try {
Files.copy(sourcePath, targetPath);
System.out.println("File copied successfully to: " + targetPath);
} catch (FileAlreadyExistsException e) {
System.err.println("Error: Target file already exists at " + targetPath + ". Use REPLACE_EXISTING to overwrite.");
} catch (IOException e) {
System.err.println("Error copying file: " + e.getMessage());
e.printStackTrace();
}
}
}
b. Copying and Overwriting an Existing File
To overwrite the target file if it already exists, use StandardCopyOption.REPLACE_EXISTING
.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class FileCopyOverwrite {
public static void main(String[] args) {
Path sourcePath = Paths.get("data/source.txt");
Path targetPath = Paths.get("data/existing_target.txt");
try {
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
System.out.println("File copied successfully (overwriting if target existed) to: " + targetPath);
} catch (IOException e) {
System.err.println("Error copying file with overwrite: " + e.getMessage());
e.printStackTrace();
}
}
}
c. Copying with Attributes
You can also copy file attributes like the last modified time along with the content using StandardCopyOption.COPY_ATTRIBUTES
.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class FileCopyWithAttributes {
public static void main(String[] args) {
Path sourcePath = Paths.get("data/source.txt");
Path targetPath = Paths.get("data/target_with_attributes.txt");
try {
Files.copy(sourcePath, targetPath,
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);
System.out.println("File copied successfully with attributes to: " + targetPath);
} catch (IOException e) {
System.err.println("Error copying file with attributes: " + e.getMessage());
e.printStackTrace();
}
}
}
Other Files.copy()
Overloads:
The Files
class also provides overloads for copying between streams and paths, which can be useful when you have data as an InputStream
or need to write to an OutputStream
.
long copy(InputStream in, Path target, CopyOption... options)
: Copies all bytes from an input stream to a file.long copy(Path source, OutputStream out)
: Copies all bytes from a file to an output stream.
d. Copying from an InputStream
to a Path
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class StreamToPathCopy {
public static void main(String[] args) {
Path targetPath = Paths.get("data/copied_from_stream.txt");
// Simulate an InputStream, e.g., from a network connection, resource, or another file
Path sourceFileForStream = Paths.get("data/stream_source.txt"); // Create this file for testing
try (InputStream in = Files.newInputStream(sourceFileForStream)) {
Files.copy(in, targetPath, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Content copied from InputStream to Path: " + targetPath);
} catch (IOException e) {
System.err.println("Error copying stream to file: " + e.getMessage());
e.printStackTrace();
}
}
}
e. Copying from a Path
to an OutputStream
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; // For creating/truncating OutputStream
public class PathToStreamCopy {
public static void main(String[] args) {
Path sourcePath = Paths.get("data/path_to_stream_source.txt"); // Create this file for testing
Path targetFileForStream = Paths.get("data/copied_to_stream.txt");
// Create an OutputStream that will write to targetFileForStream
try (OutputStream out = Files.newOutputStream(targetFileForStream,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING)) {
Files.copy(sourcePath, out);
System.out.println("Content copied from Path to OutputStream: " + targetFileForStream);
} catch (IOException e) {
System.err.println("Error copying file to stream: " + e.getMessage());
e.printStackTrace();
}
}
}
2. Legacy Approach (Less Recommended for New Code)
Before Java 7's NIO.2 API, file copying was typically done by reading from a FileInputStream
and writing to a FileOutputStream
byte by byte, or using a buffer. While still functional, this approach is more verbose, requires manual resource management, and is generally less efficient for large files unless optimized with appropriate buffer sizes.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;
public class LegacyFileCopy {
public static void main(String[] args) {
File sourceFile = new File("data/old_source.txt"); // Replace with your source file
File targetFile = new File("data/old_target.txt"); // Replace with your target file
try (FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(targetFile)) {
byte[] buffer = new byte[1024]; // Buffer size for efficiency
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
System.out.println("File copied successfully using legacy streams to: " + targetFile.getAbsolutePath());
} catch (IOException e) {
System.err.println("Error copying file using legacy streams: " + e.getMessage());
e.printStackTrace();
}
}
}
For modern Java development, stick to the java.nio.file.Files.copy()
methods as they are more robust, concise, and optimized.
[[Java File Operations]]