CodeGym /Các khóa học /C# SELF /Tạo và xóa thư mục ( Direct...

Tạo và xóa thư mục ( Directory)

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

1. Giới thiệu

Hãy tưởng tượng bạn viết một chương trình mà người dùng tải lên ảnh của họ. Tốt hơn là lưu chúng không chỉ "lộn xộn" trong một thư mục mà nên tạo các thư mục riêng — theo ngày, theo tên người dùng, tùy thích. Hoặc chương trình của bạn sinh báo cáo: hợp lý khi gom kết quả vào một thư mục riêng, và thư mục đó cần được tạo khi chạy. Xóa các thư mục tạm sau khi xong việc là trách nhiệm của mã tốt (và giúp người dùng đỡ rác).

Làm việc với thư mục là nhiệm vụ tiêu chuẩn trong nhiều ứng dụng: từ backup tới game muốn lưu save theo thư mục. Khi phỏng vấn cái này cũng hay hỏi, vì quan trọng không chỉ biết lệnh "tạo" hay "xóa" mà còn hiểu hành vi trong các tình huống không chuẩn.

Thư mục (folder) về bản chất là một container cho các file và thư mục khác trong filesystem. Các thư mục tạo thành cấu trúc cây (filesystem tree): mỗi thư mục có parent trừ gốc, và có thể có nhiều thư mục con — thậm chí hàng nghìn.

2. Cách tạo thư mục? Static class Directory

Cách đơn giản nhất để tạo thư mục là dùng phương thức static Directory.CreateDirectory. Không cần khởi tạo object nào, chỉ truyền đường dẫn:

using System.IO;

// Tạo thư mục "Reports" trong thư mục hiện tại
Directory.CreateDirectory("Reports");

Nếu thư mục đó đã tồn tại, method không làm gì và không ném lỗi — bạn có thể gọi CreateDirectory thoải mái mà không cần lo nó đã tồn tại hay chưa.

Thử truyền một đường dẫn phức tạp hơn, ví dụ tạo cả thư mục lồng nhau:

Directory.CreateDirectory(@"Data\Photos\2024\June");

Gọi này sẽ tạo cả chuỗi thư mục nếu một vài thư mục trung gian chưa tồn tại. Đây gọi là tạo đệ quy — Directory.CreateDirectory lo cho bạn mọi thứ.

Quan trọng! Trong đường dẫn hãy dùng hoặc double backslash (\\) cho Windows, hoặc slash (/). Tốt hơn nữa là dùng Path.Combine, như đã nói trước đó.

Phương thức CreateDirectory trả về gì?

Method trả về một object kiểu DirectoryInfo. Tiện khi bạn muốn thao tác tiếp với thư mục đó ngay:

DirectoryInfo reportsDir = Directory.CreateDirectory("Reports");
Console.WriteLine($"Đã tạo thư mục: {reportsDir.FullName}");

Làm sao biết thư mục có tồn tại?

Khi muốn thực hiện thao tác với thư mục, tốt là kiểm tra xem nó có tồn tại không. Có method static để làm việc này:

bool exists = Directory.Exists("Reports");
if (!exists)
{
    Console.WriteLine("Không tìm thấy thư mục, sẽ tạo ngay!");
    Directory.CreateDirectory("Reports");
}

Ghi nhớ: Không bắt buộc phải kiểm tra trước khi tạo: method không phá gì nếu thư mục đã có. Nhưng nếu bạn muốn hiện thông báo đẹp cho người dùng hoặc xử lý logic khác nhau thì cách này hữu ích.

3. Tạo thư mục: các trường hợp thực tế

Ghép kiến thức vào ứng dụng học. Giả sử chúng ta quản lý hồ sơ người dùng và muốn lưu cho mỗi người một thư mục riêng:

// Thêm System.IO lên đầu file nếu chưa có
using System.IO;

Console.Write("Nhập tên người dùng: ");
string userName = Console.ReadLine() ?? "Unknown";

// Ghép đường dẫn tới thư mục người dùng
string basePath = "UsersData";
string userPath = Path.Combine(basePath, userName);

// Tạo thư mục cho người dùng (và thư mục cha nếu cần)
Directory.CreateDirectory(userPath);

Console.WriteLine($"Thư mục cho người dùng \"{userName}\" đã sẵn sàng: {Path.GetFullPath(userPath)}");

Ví dụ trên sẽ tạo cấu trúc file (nếu chưa có):


UsersData/
  └── TenNguoiDung/

MẸO: luôn dùng Path.Combine khi ghép các phần đường dẫn — code của bạn sẽ chạy đúng trên Windows lẫn Linux/Mac.

4. Cách xóa thư mục? Method Directory.Delete

Xóa thư mục gần như đơn giản như tạo. Nhưng có vài điều cần lưu ý.

Directory.Delete("Reports");

Nếu thư mục tồn tại và trống — nó sẽ bị xóa. Nhưng nếu bên trong có gì đó, sẽ ném ngoại lệ:
System.IO.IOException: "The directory is not empty."

Còn nếu muốn xóa cả thư mục cùng nội dung?

Có overload với tham số recursive: true:

Directory.Delete("Reports", recursive: true);

CẢNH BÁO: Xóa đệ quy sẽ phá hết mọi thứ bên trong thư mục không thể phục hồi. Nếu chỉ định nhầm đường dẫn, có thể mất dữ liệu quan trọng. Luôn kiểm tra đường dẫn kĩ!

Ví dụ

Thêm tùy chọn xóa thư mục người dùng (ví dụ khi người dùng xóa tài khoản):

// Hỏi có cần xóa không
Console.Write("Xóa thư mục người dùng? (y/n): ");
string input = Console.ReadLine() ?? "";

if (input.ToLower() == "y")
{
    if (Directory.Exists(userPath))
    {
        // Xóa cùng toàn bộ nội dung
        Directory.Delete(userPath, recursive: true);
        Console.WriteLine("Đã xóa thư mục người dùng!");
    }
    else
    {
        Console.WriteLine("Thư mục không tồn tại nữa.");
    }
}

5. Bảng: Các phương thức chính làm việc với thư mục

Thao tác Phương thức Đặc điểm
Tạo thư mục
Directory.CreateDirectory(path)
Tạo đệ quy tất cả các thư mục theo đường dẫn
Kiểm tra tồn tại
Directory.Exists(path)
Trả về true hoặc false
Xóa thư mục trống
Directory.Delete(path)
Sẽ ném lỗi nếu thư mục không trống
Xóa thư mục cùng nội dung
Directory.Delete(path, recursive: true)
Xóa tất cả nội dung bên trong, không thể phục hồi
Lấy danh sách tệp
Directory.GetFiles(path)
Trả về tên các tệp
Lấy danh sách thư mục con
Directory.GetDirectories(path)
Trả về tên các thư mục

6. Những điểm không rõ ràng và lỗi thường gặp

Lỗi khi tạo: không có quyền hoặc đường dẫn không hợp lệ

Nếu bạn cố tạo thư mục trong các thư mục hệ thống (ví dụ "C:\Windows\System32\SuperApp"), rất có thể sẽ nhận được UnauthorizedAccessException hoặc IOException.

Mẹo nhỏ:

Luôn xử lý lỗi bằng try-catch khi làm việc với thư mục ngoài (ví dụ trên USB của người dùng hoặc ổ mạng).

Đừng tin tưởng đường dẫn do người dùng nhập thẳng vào.

try
{
    Directory.CreateDirectory(pathFromUser);
}
catch (Exception ex)
{
    Console.WriteLine($"Không thể tạo thư mục: {ex.Message}");
}

Xóa thư mục khi nó đang được tiến trình khác sử dụng

Nếu ai đó (hoặc chính chương trình của bạn) đang mở file trong thư mục và giữ file đó, khi cố xóa thư mục bạn sẽ nhận IOException — "không thể xóa, thư mục đang được sử dụng". Trước hết hãy đóng tất cả file bên trong thư mục.

Thư mục không trống nhưng bạn quên recursive: true

Vấn đề rất phổ biến. Nếu không truyền recursive: true mà thư mục không trống — sẽ có ngoại lệ.

Dùng đường dẫn tuyệt đối cho các thao tác quan trọng

Làm việc với đường dẫn tương đối ("Reports") luôn theo current working directory của ứng dụng. Nếu chương trình chạy từ chỗ khác, thư mục sẽ được tạo không ở nơi bạn mong đợi. Kiểm tra nơi chạy code hoặc cung cấp đường dẫn đầy đủ ngay:

string fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyAppData");
Directory.CreateDirectory(fullPath);
2
Nhiệm vụ
C# SELF, mức độ, bài học
Đã khóa
Tạo cấu trúc thư mục tùy chỉnh
Tạo cấu trúc thư mục tùy chỉnh
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION