CodeGym /Các khóa học /JAVA 25 SELF /Làm việc với tệp và thư mục tạm thời

Làm việc với tệp và thư mục tạm thời

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

1. Tạo tệp tạm: Files.createTempFile

Tệp tạm được dùng để lưu trữ dữ liệu trung gian, bộ nhớ đệm (cache) hoặc bất kỳ kết quả nào không hướng tới lưu trữ lâu dài. Thông thường, chúng tồn tại đúng bằng thời gian chương trình chạy, hoặc cho đến khi không còn cần thiết nữa.

Phần lớn tệp tạm được dùng khi tải về các tài liệu lớn (trước tiên tải vào thư mục tạm, sau đó chuyển đến vị trí mong muốn), khi caching các thông tin có thể tính toán lại hoặc lấy lại, để lưu kết quả trung gian khi xử lý tập dữ liệu lớn, cũng như để trao đổi dữ liệu giữa các phần của chương trình hoặc giữa các luồng. Một kịch bản phổ biến khác — kiểm thử: ghi vào tệp tạm thuận tiện hơn là làm bừa bộn các thư mục làm việc.

Có thể nói tệp tạm là bản nháp của chương trình. Không dành cho người dùng cuối, nhưng không có chúng thì đôi khi không làm việc được.

Trong Java, tạo tệp như vậy rất đơn giản — chỉ một dòng. Có phương thức Files.createTempFile.

Ví dụ đơn giản

import java.nio.file.*;

public class TempFileExample {
    public static void main(String[] args) throws Exception {
        // Tạo tệp tạm với tiền tố "myapp_" và hậu tố ".tmp"
        Path tempFile = Files.createTempFile("myapp_", ".tmp");
        System.out.println("Tệp tạm đã được tạo: " + tempFile);

        // Có thể ghi dữ liệu vào đó
        Files.writeString(tempFile, "Đây là dữ liệu tạm");

        // Đọc lại
        String data = Files.readString(tempFile);
        System.out.println("Nội dung: " + data);
    }
}

Điều gì xảy ra?

  • Tệp được tạo trong thư mục tạm của hệ thống (thường là "/tmp" trên Linux hoặc "C:\\Users\\<username>\\AppData\\Local\\Temp" trên Windows).
  • Tên tệp sẽ có dạng như "myapp_1234567890.tmp".
  • Tệp đã tồn tại trên đĩa, bạn có thể làm việc với nó như bình thường.

Tham số của phương thức

  • Tham số thứ nhất — tiền tố của tên tệp (ví dụ, "myapp_").
  • Tham số thứ hai — hậu tố (ví dụ, ".tmp"). Nếu không chỉ định, sẽ là ".tmp".
  • Nếu cả hai tham số đều null, tên sẽ dùng mặc định.

Lưu tệp ở đâu?

Mặc định, tệp được lưu trong thư mục tạm của hệ thống. Nhưng bạn có thể chỉ định thư mục của riêng mình:

Path tempDir = Paths.get("my_temp_folder");
Files.createDirectories(tempDir); // Tạo nếu chưa tồn tại
Path tempFile = Files.createTempFile(tempDir, "prefix_", ".txt");

2. Tạo thư mục tạm: Files.createTempDirectory

Đôi khi bạn không chỉ cần một tệp tạm, mà là cả một thư mục tạm — ví dụ để giải nén một kho lưu trữ hoặc tạm giữ nhiều tệp.

Ví dụ

import java.nio.file.*;

public class TempDirExample {
    public static void main(String[] args) throws Exception {
        // Tạo thư mục tạm với tiền tố "work_"
        Path tempDir = Files.createTempDirectory("work_");
        System.out.println("Thư mục tạm: " + tempDir);

        // Có thể tạo tệp trong đó
        Path fileInTempDir = Files.createTempFile(tempDir, "file_", ".dat");
        System.out.println("Tệp tạm bên trong: " + fileInTempDir);
    }
}

Đặc điểm:

  • Tên thư mục sẽ như sau: "work_1234567890".
  • Mặc định — trong thư mục tạm của hệ thống, nhưng có thể chỉ định thư mục khác.

Chỉ định thư mục

Path baseDir = Paths.get("my_temp_work");
Files.createDirectories(baseDir);
Path tempDir = Files.createTempDirectory(baseDir, "session_");

3. Xóa tệp và thư mục tạm

Đây là một trong những “cạm bẫy” chính của Java: tệp và thư mục tạm không tự động bị xóa! Nếu bạn không xóa chúng, chúng sẽ nằm trên đĩa trong nhiều năm (hoặc cho đến lần dọn dẹp tiếp theo của hệ thống).

Xóa tệp tạm như thế nào?

  • Thủ công: sau khi kết thúc làm việc với tệp, hãy gọi Files.delete(...) hoặc Files.deleteIfExists(...).
  • Khi kết thúc chương trình: có thể dùng phương thức cổ điển File.deleteOnExit(), nhưng chỉ cho đối tượng kiểu File, không áp dụng cho Path.

Ví dụ: xóa tệp tạm

import java.nio.file.*;

public class TempFileDeleteExample {
    public static void main(String[] args) throws Exception {
        Path tempFile = Files.createTempFile("demo_", ".tmp");
        System.out.println("Đã tạo: " + tempFile);

        // ... làm việc với tệp

        // Xóa tệp
        Files.deleteIfExists(tempFile);
        System.out.println("Đã xóa: " + tempFile);
    }
}

Sử dụng deleteOnExit()

import java.io.File;

public class DeleteOnExitDemo {
    public static void main(String[] args) throws Exception {
        File tempFile = File.createTempFile("legacy_", ".tmp");
        System.out.println("Đã tạo: " + tempFile);

        // Đánh dấu tệp sẽ bị xóa khi JVM kết thúc
        tempFile.deleteOnExit();
    }
}

Lưu ý!
Phương thức deleteOnExit() chỉ hoạt động với File, không phải Path. Nếu bạn dùng API hiện đại (PathFiles), hãy xóa thủ công.

Xóa thư mục tạm

Chỉ có thể xóa thư mục tạm nếu nó rỗng:

Files.delete(tempDir); // ném ngoại lệ nếu bên trong còn thứ gì đó

Nếu trong thư mục còn tệp — hãy xóa chúng trước, rồi mới xóa thư mục. Thông thường người ta viết một phương thức đệ quy nhỏ cho việc này.

4. Khuyến nghị thực tế

Lưu tệp tạm ở đâu?

Thư mục tạm của hệ thống:
Dùng mặc định nếu không có yêu cầu đặc biệt. Có thể lấy đường dẫn như sau:

String tempDir = System.getProperty("java.io.tmpdir");
System.out.println("Thư mục tạm của hệ thống: " + tempDir);

Thư mục riêng:
Nếu bảo mật hoặc tổ chức quan trọng — hãy tạo một thư mục riêng (ví dụ, bên trong thư mục ứng dụng).

Bảo mật

  • Không lưu tệp tạm trong các thư mục công cộng — đặc biệt nếu có thể chứa thông tin bí mật.
  • Hãy dọn tệp tạm sau khi sử dụng — nếu không chúng có thể tích tụ và chiếm dung lượng.

Dọn dẹp khi có lỗi

Nếu trong quá trình thực thi chương trình xảy ra lỗi, đừng quên xóa các tệp tạm. Để làm việc này tiện lợi, hãy dùng các khối try-finally:

Path tempFile = Files.createTempFile("task_", ".tmp");
try {
    // sử dụng tệp
} finally {
    Files.deleteIfExists(tempFile);
}

Tệp tạm và kiểm thử

Trong kiểm thử thường dùng tệp và thư mục tạm để cô lập dữ liệu. Sau khi kiểm thử — nhất định phải xóa mọi thứ đã tạo!

5. Ví dụ: thư mục làm việc tạm để xử lý dữ liệu

Giả sử bạn viết một chương trình xử lý một kho lưu trữ và tạm thời giải nén các tệp. Khi đó thuận tiện là tạo một thư mục tạm, và sau khi hoàn tất — xóa nó.

import java.nio.file.*;
import java.io.IOException;

public class TempWorkDirExample {
    public static void main(String[] args) throws IOException {
        // Tạo thư mục tạm
        Path tempWorkDir = Files.createTempDirectory("unzip_");
        System.out.println("Thư mục làm việc tạm: " + tempWorkDir);

        try {
            // Ở đây có thể là phần giải nén kho lưu trữ
            Path tempFile = Files.createTempFile(tempWorkDir, "file_", ".txt");
            Files.writeString(tempFile, "Dữ liệu tạm để xử lý");

            // ... làm việc với các tệp

        } finally {
            // Xóa tất cả tệp trong thư mục và chính thư mục đó
            Files.walk(tempWorkDir)
                .sorted((a, b) -> b.compareTo(a)) // trước tệp, sau thư mục
                .forEach(path -> {
                    try {
                        Files.deleteIfExists(path);
                    } catch (IOException ex) {
                        System.err.println("Không thể xóa " + path + ": " + ex.getMessage());
                    }
                });
            System.out.println("Đã xóa thư mục tạm và các tệp.");
        }
    }
}

Lưu ý:
Trước tiên xóa tất cả tệp, sau đó mới xóa thư mục. Cần sắp xếp để không cố xóa thư mục trước khi đã xóa nội dung của nó.

6. Các lỗi thường gặp khi làm việc với tệp tạm

Lỗi số 1: quên xóa tệp hoặc thư mục tạm. Vấn đề phổ biến nhất — tệp tạm còn lại trên đĩa, tích tụ và theo thời gian dẫn tới “rác” hệ thống. Điều này đặc biệt nghiêm trọng với ứng dụng máy chủ và các tiến trình chạy lâu.

Lỗi số 2: dùng deleteOnExit() cho Path. Phương thức deleteOnExit() chỉ làm việc với lớp File, không phải với Path. Nếu bạn dùng API hiện đại, bạn sẽ phải xóa thủ công.

Lỗi số 3: cố xóa thư mục không rỗng bằng Files.delete. Phương thức Files.delete() chỉ xóa thư mục rỗng. Nếu bên trong còn thứ gì đó — sẽ ném ngoại lệ. Để xóa thư mục không rỗng, hãy duyệt đệ quy và xóa tất cả tệp.

Lỗi số 4: tạo tệp tạm trong thư mục làm việc của dự án. Điều này có thể dẫn tới việc vô tình xóa tệp quan trọng hoặc gây rối. Tốt hơn là dùng thư mục tạm của hệ thống hoặc một thư mục riêng cho tệp tạm của ứng dụng.

Lỗi số 5: không xử lý ngoại lệ khi xóa tệp tạm. Nếu tệp đã bị xóa hoặc đang bị khóa, thao tác xóa có thể ném ngoại lệ. Hãy dùng Files.deleteIfExists() và xử lý lỗi.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION