Làm việc với File và Directory trong C#


.NET Framework cung cấp cho chúng ta namespace System.IO để làm việc với thư mục và tập tin trên máy tính. Bài viết sau đây sẽ hướng dẫn các bạn một số phương thức và lớp rất hữu dụng khi thao tác với tập tin/thư mục.

Trong tất cả các đoạn code sau này, chúng ta lưu ý đều phải có chỉ dẫn tham chiếu đến System.IO như sau ở đầu:
using System.IO;

  1. Lấy thông tin về File, Directory hoặc Drive
    Thông qua các lớp FileInfo, DirectoryInfoDriveInfo, chúng ta có thể lấy được thông tin về đối tượng như: ngày khởi tạo, kích thước, phần mở rộng, thuộc tính… Ví dụ sau đây cho phép chúng ta nhập vào đường dẫn đến một tập tin và sẽ hiển thị thông tin về tập tin, thư mục cha và ổ đĩa chứa tập tin đó.

    using System;
    using System.Collections.Generic;
    using System.IO;
    namespace Example
    {
        class Test
        {
            public static void Main()
            {
                Console.Write("Enter file path:");
                string filePath = Console.ReadLine();
                Console.WriteLine("File Information");
                FileInfo fileInfo = new FileInfo(filePath);
                if (fileInfo.Exists)
                {
                    Console.WriteLine("Creation Time: " + fileInfo.CreationTime.ToString());
                    Console.WriteLine("Last Access Time: " + fileInfo.LastAccessTime.ToString());
                    Console.WriteLine("File Length (bytes): " + fileInfo.Length.ToString());
                    Console.WriteLine("File Attributes: " + fileInfo.Attributes.ToString());
                }
                Console.WriteLine();
                Console.WriteLine("Directory Information");
                DirectoryInfo directoryInfo = fileInfo.Directory;
                if (directoryInfo.Exists)
                {
                    Console.WriteLine("Creation Time: " + directoryInfo.CreationTime.ToString());
                    Console.WriteLine("Last Access Time: " + directoryInfo.LastAccessTime.ToString());
                    Console.WriteLine("Directory contains: " + directoryInfo.GetFiles().Length.ToString() + " files");
                }
                Console.WriteLine();
                Console.WriteLine("Drive Information");
                DriveInfo driveInfo = new DriveInfo(fileInfo.FullName);
                if (driveInfo.IsReady)
                {
                    Console.WriteLine("Drive Name: " + driveInfo.Name);
                    Console.WriteLine("Drive Type: " + driveInfo.DriveType.ToString());
                    Console.WriteLine("Drive Format: " + driveInfo.DriveFormat.ToString());
                    Console.WriteLine("Drive Free Space: " + driveInfo.AvailableFreeSpace.ToString());
                }
                Console.ReadKey();
            }
        }
    }
    
    Đầu tiên, chúng ta sẽ yêu cầu người dùng nhập vào đường dẫn đến một tập tin bất kỳ trên máy tính. Dựa trên đường dẫn này, chúng ta sẽ tạo ra đối tượng FileInfo để lấy thông tin về tập tin
    Console.Write("Enter file path:");
    string filePath = Console.ReadLine();
    FileInfo fileInfo = new FileInfo(filePath);

    Điều mà trước hết phải làm là kiểm tra xem thử tập tin này có thực sự tồn tại hay không. Lưu ý là mặc dù đường dẫn của chúng ta có đúng hay sai thì đối tượng fileInfo vẫn sẽ được tạo ra (không bao giờ NULL). Chúng ta sẽ dựa vào thuộc tính Exists để kiểm tra xem tập tin đó có tồn tại hay không. Sau khi đã kiểm tra được chắn chắn là tập tin này tồn tại, chúng ta lấy ra các thông tin về tập tin đó bao gồm: Thời gian khởi tạo, Thời gian truy cập cuối cùng, Thuộc tính và Kích thước của tập tin. Ngoài ra, chúng ta còn có thể lấy được các thông tin khác từ đối tượng FileInfo cũng như nhiều phương thức có thể được gọi từ lớp này (chi tiết xem tại MSDN: FileInfo)

    Việc tiếp theo là chúng ta in ra thông tin thư mục chứa tập tin đã chỉ định. Thuộc tính Directory của fileInfo sẽ trả về một đối tượng DirectoryInfo của thư mục cha, dựa trên đối tượng này, chúng ta có thể lấy ra thông tin của thư mục tương tự như thông tin của tập tin:

     

    DirectoryInfo directoryInfo = fileInfo.Directory;
    if (directoryInfo.Exists)
    {
        Console.WriteLine("Creation Time: " + directoryInfo.CreationTime.ToString());
        Console.WriteLine("Last Access Time: " + directoryInfo.LastAccessTime.ToString());
        Console.WriteLine("Directory contains: " + directoryInfo.GetFiles().Length.ToString() + " files");
    }

    Cuối cùng, chúng ta lấy thông tin về ổ đĩa chứa tập tin đã chỉ định. Lưu ý rằng đối tượng FileInfo không có thuộc tính nào để trả về đối tượng DriveInfo của ổ đĩa chứa nó, do đó chúng ta sẽ phải tạo ra một đối tượng DriveInfo bằng cách truyền vào hàm khởi tạo của nó một đường dẫn hợp lệ bắt đầu từ ổ đĩa đó. Sau đó, chúng ta phải kiểm tra thuộc tính IsReady của ổ đĩa này nhằm chắc chắn rằng nó thực sự tồn tại (ví dụ trong trường hợp chúng ta lấy về thông tin ổ đĩa DVD mà lại chưa bỏ đĩa vào thì chắc chắn IsReady của nó bằng False)

     

    DriveInfo driveInfo = new DriveInfo(fileInfo.FullName);
    if (driveInfo.IsReady)
    {
        Console.WriteLine("Drive Name: " + driveInfo.Name);
        Console.WriteLine("Drive Type: " + driveInfo.DriveType.ToString());
        Console.WriteLine("Drive Format: " + driveInfo.DriveFormat.ToString());
        Console.WriteLine("Drive Free Space: " + driveInfo.AvailableFreeSpace.ToString());
    }
  2. Sao chép, di chuyển và xóa tập tin hoặc thư mục

    Dựa trên các đối tượng FileInfo và DriveInfo đã tạo ra ở trên mà chúng ta có thể gọi các phương thức để thực hiện việc Sao chép, di chuyển và xóa tập tin/thư mục. Các phương thức quan trọng của các lớp FileInfo là:

    • CopyTo: Sao chép tập tin đến đường dẫn được chỉ định và trả về đối tượng FileInfo của tập tin vừa được sao chép. Ví dụ sao chép tập tin đến ổ C: fileInfo.CopyTo(@“C:\” + fileInfo.Name); (các bạn lưu ý kí tự @ trước chuỗi để khỏi phải gõ ký tự \ hai lần.
    • Delete: Xóa tập tin vĩnh viễn nếu nó thực sự tồn tại. Lưu ý rằng phương thức này sẽ xóa trực tiếp tập tin vĩnh viễn chứ không phải là di chuyển tập tin đó đến thùng rác. Phiên bản hiện tại của C# không có cung cấp phương thức nào để chúng ta di chuyển tập tin đến thùng rác mà chúng ta cần phải tham chiếu đến thư viện của Visual Basic. Xem thêm tại: Delete File to Recycle Bin in C#
    • MoveTo: Di chuyển tập tin này đến vị trí mới. Phương thức này cũng được dùng để đổi tên một tập tin mà không thay đổi đường dẫn của nó. Ví dụ di chuyển tập tin đến ổ C: fileInfo.MoveTo(@”C:\” + fileInfo.Name);
    • Replace: Thay thế nội dung của tập tin nào đó được chỉ định bằng nội dung của tập tin chứa trong đối tượng FileInfo
    Đối với thư mục thì chúng ta có các phương thức sau đây nằm trong lớp DirectoryInfo:
    • Create: Tạo ra một thư mục mới từ đối tượng DirectoryInfo
    • CreateSubdirectory: Tạo ra thư mục con chứa trong đường dẫn được chỉ định
    • Delete: Xóa thư mục
    • MoveTo: Di chuyển thư mục (kể cả nội dung bên trong) đến đường dẫn mới nằm trên cùng một ổ đĩa. Phương thức MoveTo cũng được dùng để đổi tên thư mục.
  3. Làm việc với các lớp Path, File và Directory

    Lớp Path cung cấp cho chúng ta các phương thức tĩnh tiện ích nhằm thao tác với đường dẫn của tập tin hoặc thư mục. Một vài phương thức phổ biến trong Path là: 

     

    • Combine: Kết hợp một mảng các đường dẫn với nhau và trả về một đường dẫn duy nhất. Ví dụ: Path.Combine(@”C:\abc\”, @”efg\file.txt”); sẽ trả về C:\abc\efg\file.txt
    • GetDirectoryName: Trả về đường dẫn đến thư mục chứa tập tin trong đường dẫn đó. Ví dụ: Path.GetDirectoryName(@”C:\abc\file.txt”) sẽ trả về chuỗi C:\abc
    • GetExtension: Trả về phần mở rộng của tập tin được chỉ định. Ví dụ: Path.GetExtension(“Download.rar”) sẽ trả về chuỗi “.rar”
    • GetFileName: Lấy tên của tập tin từ đường dẫn được chỉ định. Tên tập tin được trả về sẽ bao gồm cả phần mở rộng. Nếu chỉ muốn lấy tên không thôi thì sử dụng phương thức GetFileNameWithoutExtension
    • GetFullPath: Trả về đường dẫn đầy đủ đến tập tin được chỉ định. Đường dẫn này sẽ dựa trên thư mục hiện tại của ứng dụng chạy. Ngoài ra, lớp Path còn có các phương thức tiện ích khác hỗ trợ rất nhiều khi lập trình, chi tiết xem tại: MSDN: Path class
    Lớp FileDirectory được dùng để thao tác trên tập tin và thư mục tương tự như lớp FileInfoDirectoryInfo. Tuy nhiên, điểm khác biệt là chúng ta sẽ thao tác chủ yếu qua các đường dẫn đến tập tin/thư mục chứ không cần phải tạo ra một đối tượng FileInfo hoặc DirectoryInfo. Một số ví dụ:
    //Sao chép tập tin
    File.Copy(@"C:\abc.txt", @"F:\Temp\test.txt");
    //Xóa tập tin
    File.Delete(@"C:\abc.txt");
    //Di chuyển tập tin
    File.Move(@"C:\abc.txt", @"F:\Temp\test.txt");
    
    //trả về mảng chuỗi các tập tin trong thư mục MyFolder của ổ đĩa C
    Directory.GetFiles(@"C:\MyFolder\");

    Các bạn có thể xem thêm tại MSDN: File classDirectory class

     

  4. Tổng kết:

    Trong bài hôm nay, chúng ta đã tìm hiểu qua về cách thức lấy thông tin từ tập tin, thư mục và ổ đĩa cũng như một số thao tác cơ bản như Sao chép, Di chuyển, Xóa. Chúng ta cũng đã tìm hiểu qua về những phương thức tĩnh trong các lớp Path, File và Directory để làm việc dựa trên các đường dẫn đến tập tin và thư mục. Có một lưu ý khi các bạn làm việc với các tập tin, thư mục là chúng ta cần phải quan tâm đến quyền truy nhập đến tập tin/thư mục đó là như thế nào để chắc chắn ứng dụng của chúng ta hoạt động bình thường trên các máy tính khác nhau. Trong bài tiếp theo, chúng ta sẽ tìm hiểu làm thế nào để tạo một cây thư mục như trong Windows Explorer bằng TreeView. Thân,

Your power is your mind!

Tác giả: xuanchien

Tran Xuan Chien. Japan Advanced Institute of Science and Technology - Japan. Senior Developer - NUS Technology.

48 thoughts on “Làm việc với File và Directory trong C#”

    1. Không hiểu ý của em lắm. Nếu như muốn lấy ra kiểu file thì chỉ cần lấy phần mở rộng của File bằng phương thức Path.GetExtension hoặc là thuộc tính Extension của FileInfo là được.

  1. a ơi cho e hỏi sao e dùng phương thức Directory.Move di chuyển 2 thư mục ở 2 ổ đĩa khác nhau thì nó báo lỗi này “Source and destination path must have identical roots. Move will not work across volumes”.Còn khi di chuển cùng ổ đĩa thì ok.

    1. Á, cảm ơn em đã chỉ ra lỗi. Anh quên mất là Directory.Move thì nó cũng tương tự như MoveTo của DirectoryInfo. Để di chuyển 2 thư mục thì em có thể làm như sau:
      – Tạo thư mục ở đường dẫn đích (phương thức Create của DirectoryInfo)
      – Sao chép tất cả các tập tin bên trong thư mục nguồn sang thư mục đích
      – Sao chép tất cả các thư mục bên trong thư mục nguồn sang thư mục đích
      – Xóa thư mục nguồn.

      1. vậy là phải viết đệ quy giống hàm Copy thư mục rồi.Bài viết của anh rất hay thank anh rất nhiều🙂

  2. anh Chiến cho em hỏi, trong cái đồ án mẫu của anh. Khi em thử điểu chỉnh để cho khi view details thì khi ấn vào folder nào cũng hiện lên detail của folder đó , nhưng khi chỉnh như thế thì mình sẽ ko new folder và rename đc , còn khi bỏ cái detail đó đi thì mình lại new folder đc. Anh chiên có cách nào giải quyết để vừa view detail all trên tất cả các folder vừa new folder được ko. À nhân tiện cho em hỏi cái phần load address bar lun

      1. Cho em hỏi 1 chút: Mình đang ở tại một vị trí hiện hành trên 1 đường dẫn, làm thế nào thế hiện cập nhật (vừa mới tạo xong 1 thư mục hay xoá 1 thư mục xong).

  3. cho em hỏi làm sao copy 1 cái folder này qua thư mục khác được trong khi DirectoryInfo chỉ có move to thôi
    còn fileinfo thì chỉ copy được 1 cái tập tin

  4. Anh ơi cho hỏi trình tự mình làm mấy cái button có liên quan tới lịch sử trong Explorer như: back, forward ?
    Em cảm ơn anh nhiều nhiều.

    1. Theo anh hiểu thì em đang hỏi về chức năng của các nút này. Trong ứng dụng của em, em có thể sử dụng một List để lưu trữ lại toàn bộ các đường dẫn mình đã vào như là history, đồng thời có một biến index để lưu trữ lại vị trí hiện tại mình đang đứng trong List đó.
      – Mặc định thì khi em nhấn vào một thư mục nào đó, em sẽ thêm đường dẫn đến thư mục này vào List và index sẽ chỉ đến vị trí cuối cùng trong List.
      – Khi nhấn back, em cho index giảm đi 1 và lấy ra đường dẫn tương ứng. Khi nhấn next, nếu index ko phải ở cuối cùng của List thì em tăng index lên 1 và lấy ra đường dẫn tương ứng.
      – Nếu ngườNếu mà index chỉ đến 1 vị trí nào đó không phải ở cuối cùng và người dùng duyệt đến thư mục mới thì em thực hiện xóa toàn bộ các item phía sau List bắt đầu từ vị trí index và thêm đường dẫn hiện tại vào List.
      Đó là ý tưởng cơ bản để em thiết kế chức năng History trong Explorer. Việc cài đặt cụ thể đôi khi cần phải xử lý một số tình huống nhỏ phát sinh (như kiểm tra để index luôn dương…)
      Thân

  5. em đọc trên msdn thì File và Directory không thấy hổ trở rename tên file và folder .vậy muốn rename tên file và folder thì làm thế nào hả anh

    1. Chào em. Như anh có đề cập trong bài viết thì phương thức dùng để di chuyển file cũng chính là phương thức đổi tên file nếu như thư mục nguồn và thư mục đích giống nhau.
      Thân,

  6. Anh ơi Dotnetbar sao có ít sự kiện vậy ! Có cách nào thêm sự kiện cho Dotnetbar ko anh?
    Em thấy thiếu sự kiện nhiều lắm.
    Thân

    1. Oh, cái này lâu rồi mà không thấy gì hết, hôm nay mới biết, chắc là quá trễ ^_^. Dù sao cũng trả lời em luôn. Mặc định thì một cái Control được hãng thứ ba tạo ra sẽ có các event cho control đó do hãng đó viết sẵn (và thường đáp ứng đủ nhu cầu của người dùng). Nếu em muốn thêm sự kiện thì phải kế thừa cái control đó và viết sự kiện bổ sung.
      Thân,

  7. Chào ban. Bạn cho mình hỏi là minhh muốn chuyển 1 file từ máy này qua máy khác = Code C# thì làm như thế nào, nếu máy mình chuyển file sang có đặt mật khẩu. Nếu bạn trả lời làm ơn thông báo cho mình qua Email để mình biết nhé. Chân thành cảm ơn.

    1. Việc chuyển file giữa các máy trong mạng dùng C# thì sẽ phụ thuộc vào dịch vụ mạng của Windows vì chúng ta đang sử dụng các phương thức của Windows. Do đó, nếu máy bên kia đặt mật khẩu thì rất có khả năng không thể nào truy cập được vào được. Vì vấn đề này mình chưa tìm hiểu nên không giúp được bạn nhiều.
      Thân,

  8. Chào ban. Bạn cho mình hỏi là minhh muốn chuyển 1 file từ máy này qua máy khác = Code C# thì làm như thế nào, nếu máy mình chuyển file sang có đặt mật khẩu. Nếu bạn trả lời làm ơn thông báo cho mình qua Email để mình biết nhé. Chân thành cảm ơn. mail minh là xuanchinh.apt@gmail.com

  9. Chào bạn, bạn có biết cách nào để không cho phép ĐỔI TÊN FILE không? mình search rất nhiều thì chỉ thấy có phân quyền Read write,… chứ chưa thấy ai nói về đổi tên file. Mình muốn làm ứng dụng quản lý các tiến trình trên window, có thể sử dụng tên file(đường dẫn) để quản lý nhưng nếu đổi tên thfi chương trình mất tác dụng rồi.
    Nếu có thể bạn trả lời qua mail này giúp mình nha: quangdu.qn@gmail.com
    Mọi sự giúp đỡ đều đáng trân trọng. Cảm ơn

    1. Theo anh biết thì nếu như hai máy đó bình thường đã có kết nối mạng với nhau thì mình có thể chỉ định trực tiếp đường dẫn của thư mục được chia sẻ để copy tới đó. Ví dụ: File.Copy(@”\Other-PC\SharedFolder\”, filePath);

  10. Em đang tìm hiểu cái này, nhưng viết trên Winform thì sao hả anh, mới học C# nên còn gà, mong anh chỉ thêm. Bây giờ em viết được một mô phỏng của WindownExplorer, em muốn sửa code ở trên để khi em click chọn vào một item thì có thể thao tác Copy + Cut + Pause tương tự như trong Windown. Thank anh nhiều.

  11. anh ơi cho em hỏi làm sao để lấy được type của tập tin thư mục vi dụ như là thư mục thì sẽ là: File folder ,file .txt thì sẽ là text document
    em cảm ơn!

  12. mình bên asp.net nhưng nghĩ c# và asp.net cũng gần với nhau nên hỏi chút. mình tạo 1 website có folder tên là anhbaiviet để lưu ảnh khi mình xóa bài viết thì muốn xóa luôn ảnh trong folder này thì có thể áp dụng code này được ko

  13. Được chứ bạn, code này vẫn hoạt động tốt với ASP.NET. Tuy nhiên bạn lưu ý một số website có phân quyền cho từng thư mục, vì vậy chú ý phân quyền trên thư mục mà bạn thao tác nhé.
    Thân

  14. Cho mình hỏi mình có 1 thư mục PatientImage với các file như: 00000_0001, 00000_0002, 00000_0003, 00001_0001, 000001_0002, 00003_0001, 00003_0002 ….v.v. Mình muốn đếm số file theo từng nhóm 00000, 00001, 00002, 00003 v.v
    Thanks

    1. Theo mình :
      B1 : bạn lấy toàn bộ các file đó quăng vào một ,mảng
      B2 : duyệt mảng này và thao tác tách vì đều có định dạng chung là ” _ ” ở giữa.
      song song tách bạn cho các biến đếm chạy
      b3 : hiển thị kết quả

  15. các anh ơi cho e hỏi khi copy file C#2010 từ máy này sang máy khác nó báo lỗi đường dẫn trong debug thì mình chỉnh sửa chỗ lỗi đường dẫn như thế nào để kh bị báo lỗi vậy anh!

  16. cho em hỏi : em có 1 PictureBox và 1 Button , khi em click vào, nó sẽ mở OpenFileDialog để lấy tấm hình ra và hiển thị lên PictureBox. Giờ em muốn Click vào Button thì nó sẽ Copy tấm hình lúc nãy chọn ra sang thư mục Bin/Debug/DaTa/Hinh và lấy tên file hình và phần mở rộng của file hình thì phải làm sao. file .exe của chương trinh cũng nằm trong Binn/Debug

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s