Di Chuyển Tệp Hoặc Thư Mục
(Moving a File or Directory)
Bạn có thể di chuyển một tệp hoặc thư mục bằng cách sử dụng phương thức move(Path, Path, CopyOption...). Việc di chuyển sẽ thất bại nếu tệp đích đã tồn tại, trừ khi bạn chỉ định tùy chọn REPLACE_EXISTING.
Lưu ý quan trọng
↳ Thư mục trống: Thư mục trống có thể được di chuyển.
↳ Thư mục không trống: Nếu thư mục không trống, việc di chuyển chỉ được thực hiện nếu có thể di chuyển thư mục mà không cần di chuyển các nội dung bên trong. Trên các hệ thống UNIX, việc di chuyển thư mục trong cùng một phân vùng thường chỉ là đổi tên thư mục, và trong trường hợp đó, phương thức này sẽ hoạt động ngay cả khi thư mục chứa các tệp.
Phương thức move hỗ trợ các tùy chọn varargs, với các enum StandardCopyOption sau đây:
↳ REPLACE_EXISTING: Thực hiện di chuyển ngay cả khi tệp đích đã tồn tại. Nếu đích là một liên kết biểu tượng (symbolic link), liên kết biểu tượng sẽ được thay thế, nhưng nội dung mà liên kết trỏ tới sẽ không bị ảnh hưởng.
↳ ATOMIC_MOVE: Thực hiện việc di chuyển như một thao tác tệp nguyên tử. Nếu hệ thống tệp không hỗ trợ di chuyển nguyên tử, một ngoại lệ sẽ được ném ra. Với ATOMIC_MOVE, bạn có thể di chuyển một tệp vào thư mục và được đảm bảo rằng bất kỳ quá trình nào theo dõi thư mục đó sẽ truy cập một tệp hoàn chỉnh.
(1) Ví dụ về cách di chuyển một tệp tin
Dưới đây là ví dụ về cách di chuyển một tệp bằng cách sử dụng phương thức move(Path, Path, CopyOption...):
Ví dụ: Example.java
import java.io.IOException;
import java.nio.file.*;
public class Example {
public static void main(String[] args) {
// Đường dẫn đến tệp nguồn
Path sourcePath = Paths.get("path/to/source/file.txt");
// Đường dẫn đến tệp đích
Path targetPath = Paths.get("path/to/target/file.txt");
try {
// Di chuyển tệp từ sourcePath sang targetPath, thay thế nếu tệp đích đã tồn tại
Files.move(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Tệp đã được di chuyển thành công.");
} catch (IOException e) {
System.err.println("Di chuyển tệp thất bại: " + e.getMessage());
}
}
}
Kết quả của chương trình là:
Trong ví dụ trên, bạn cần thay đổi đường dẫn sourcePath và targetPath theo nhu cầu của bạn.
(2) Ví dụ di chuyển một thư mục
Để di chuyển một thư mục, bạn có thể sử dụng phương thức Files.move(Path, Path, CopyOption...) tương tự như việc di chuyển một tệp. Dưới đây là ví dụ về cách di chuyển một thư mục:
Ví dụ: Example.java
import java.io.IOException;
import java.nio.file.*;
public class Example {
public static void main(String[] args) {
// Đường dẫn đến thư mục nguồn
Path sourceDir = Paths.get("path/to/source/directory");
// Đường dẫn đến thư mục đích
Path targetDir = Paths.get("path/to/target/directory");
try {
// Di chuyển thư mục từ sourceDir sang targetDir, thay thế nếu thư mục đích đã tồn tại
Files.move(sourceDir, targetDir, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Thư mục đã được di chuyển thành công.");
} catch (IOException e) {
System.err.println("Di chuyển thư mục thất bại: " + e.getMessage());
}
}
}
Kết quả của chương trình là:
Lưu ý rằng việc di chuyển thư mục bằng phương thức Files.move() sẽ di chuyển toàn bộ nội dung của thư mục, bao gồm cả các tệp và thư mục con.
(3) Ví dụ di chuyển thư mục đệ quy
Mặc dù bạn có thể sử dụng phương thức move trên một thư mục đơn lẻ như đã trình bày ở trên, nhưng phương thức này thường được sử dụng cùng với cơ chế duyệt cây thư mục (file tree recursion mechanism) để di chuyển toàn bộ cây thư mục. Để biết thêm thông tin, hãy tham khảo cơ chế Duyệt Cây Tệp (Walking the File Tree).
Để di chuyển một thư mục cùng với tất cả các tệp và thư mục con bên trong, bạn có thể sử dụng cơ chế duyệt cây thư mục (file tree traversal) kết hợp với việc di chuyển từng tệp và thư mục con riêng lẻ. Điều này thường được thực hiện bằng cách sử dụng lớp SimpleFileVisitor và phương thức Files.walkFileTree(). Dưới đây là ví dụ về cách di chuyển một cây thư mục đệ quy:
Ví dụ: Example.java
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
public class Example {
public static void main(String[] args) {
// Đường dẫn đến thư mục nguồn
Path sourceDir = Paths.get("path/to/source/directory");
// Đường dẫn đến thư mục đích
Path targetDir = Paths.get("path/to/target/directory");
try {
// Di chuyển thư mục nguồn đến thư mục đích
Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
// Tạo thư mục tương ứng trong đường dẫn đích
Path targetPath = targetDir.resolve(sourceDir.relativize(dir));
if (!Files.exists(targetPath)) {
Files.createDirectory(targetPath);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// Di chuyển từng tệp từ thư mục nguồn sang đích
Files.move(file, targetDir.resolve(sourceDir.relativize(file)), StandardCopyOption.REPLACE_EXISTING);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
// Xóa thư mục sau khi di chuyển tất cả các tệp và thư mục con bên trong
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
System.out.println("Thư mục đã được di chuyển thành công.");
} catch (IOException e) {
System.err.println("Di chuyển thư mục thất bại: " + e.getMessage());
}
}
}
Trong ví dụ trên, bạn cần thay đổi đường dẫn sourcePath và targetPath theo nhu cầu của bạn. Với cách này, toàn bộ cây thư mục sẽ được di chuyển từ sourceDir sang targetDir.
Hy vọng rằng qua các ví dụ trên, bạn sẽ hiểu rõ hơn về cách di chuyển tệp tin hoặc thư mục trong Java.