2012-06-08 43 views
29

Tôi đã đọc một số tập tin hướng dẫn IO cho C# và đã quản lý để viết ra một số tập tin, nhưng nếu đường dẫn tôi đưa ra có chứa thư mục thì sao?tạo tập tin, đệ quy tạo thư mục

Ví dụ: tôi muốn tạo tệp có tên data/my_file ngoại trừ data thư mục không tồn tại.

Dòng,

BinaryWriter outFile = new BinaryWriter(File.OpenWrite(path)); 

nơi path là chuỗi trên, treo với thông điệp rằng phần của đường dẫn không tồn tại, có nghĩa là C# không tạo ra chúng theo yêu cầu.

Tôi muốn C# xử lý tất cả việc tạo thư mục lộn xộn và kiểm tra cho tôi thay vì phải phân tích đường dẫn và tạo tất cả các thư mục cần thiết. Điều này có thể không? Nếu không, có một đoạn mã mà tôi chỉ có thể sao chép vào dự án của tôi mà sẽ xử lý bất cứ điều gì tôi có thể nhìn ra (vì tôi không biết nhiều về quản lý tập tin).

+0

Bạn không cần phải thêm tiền tố tiêu đề của bạn với "C#". \t Vui lòng xem "[Stack Overflow không cần kỹ năng SEO của bạn] (http://meta.stackexchange.com/a/130208)". –

Trả lời

69

System.IO.Directory.CreateDirectory() sẽ tạo tất cả thư mục và thư mục con trong một đường dẫn được chỉ định, nếu chúng chưa tồn tại.

Bạn có thể gọi nó, đi qua đường dẫn, để đảm bảo cấu trúc thư mục được tạo trước khi ghi tệp của bạn.

+0

Tuyệt vời! Mặc dù bây giờ tôi là loại tự hỏi tại sao điều này không được thực hiện tự động. Ý tôi là, có những lúc bạn không muốn tự động tạo các thư mục này nếu cần? – MxyL

+10

Nó sẽ thực sự tiện dụng cho Microsoft để cung cấp một tham số boolean cho BinaryWriter hỏi nếu bạn muốn tạo các thư mục nếu chúng không tồn tại. Tôi đoán nếu bạn * luôn luôn * làm điều đó, ai đó sẽ có một trường hợp sử dụng mà họ không muốn hành vi đó và sẽ phàn nàn rằng họ không có quyền kiểm soát nó. –

+0

Thật là tò mò rằng họ không bao gồm một tham số như vậy, xem xét 'Directory.GetFiles()' có 'SearchOption' để chỉ định tìm kiếm cấp cao nhất hoặc đệ quy. – Erik

7

Trong khi System.IO.Directory.CreateDirectory() thực sự sẽ tạo các thư mục cho bạn đệ quy, tôi gặp một tình huống mà tôi phải đưa ra phương pháp của riêng mình. Về cơ bản System.IO không hỗ trợ đường dẫn trên 260 ký tự, buộc tôi phải sử dụng thư viện Delimon.Win32.IO, làm việc với các đường dẫn dài, nhưng không tạo thư mục đệ quy.

Dưới đây là đoạn code tôi sử dụng để tạo các thư mục đệ quy:

void CreateDirectoryRecursively(string path) 
{ 
    string[] pathParts = path.Split('\\'); 

    for (int i = 0; i < pathParts.Length; i++) 
    { 
     if (i > 0) 
      pathParts[i] = Path.Combine(pathParts[i - 1], pathParts[i]); 

     if (!Directory.Exists(pathParts[i])) 
      Directory.CreateDirectory(pathParts[i]); 
    } 
} 
+2

Không Explorer chặn trên đường dẫn trên 255 ký tự? Nó hút nhưng tôi sẽ sớm cắt ngắn nó hơn là cố gắng để đối phó với crap đó. – Casey

+1

2 tuổi bump Tôi biết nhưng tôi stumbled khi câu trả lời này trong khi sửa chữa một lỗi và muốn thêm một cảnh báo cho câu trả lời này. Điều này sẽ ném "Đường dẫn không phải là một hình thức pháp lý" khi sử dụng ổ đĩa mạng (Đường dẫn bắt đầu bằng \\\). –

+0

Mã cũng sẽ thất bại nếu đường dẫn chứa ký tự ổ đĩa. – Hans

1

Vì vậy, ở trên không làm việc siêu tốt cho tôi để tạo thư mục cơ bản. Tôi sửa đổi này một chút để xử lý các trường hợp phổ biến cho các ký tự ổ đĩa và một đường dẫn với một nguồn tài nguyên tập tin vào cuối.

public bool CreateDirectoryRecursively(string path) 
    { 
     try 
     { 
      string[] pathParts = path.Split('\\'); 
      for (var i = 0; i < pathParts.Length; i++) 
      { 
       // Correct part for drive letters 
       if (i == 0 && pathParts[i].Contains(":")) 
       { 
        pathParts[i] = pathParts[i] + "\\"; 
       } // Do not try to create last part if it has a period (is probably the file name) 
       else if (i == pathParts.Length-1 && pathParts[i].Contains(".")) 
       { 
        return true; 
       } 
       if (i > 0) { 
        pathParts[i] = Path.Combine(pathParts[i - 1], pathParts[i]); 
       } 
       if (!Directory.Exists(pathParts[i])) 
       { 
        Directory.CreateDirectory(pathParts[i]); 
       } 
      } 
      return true; 
     } 
     catch (Exception ex) 
     { 
      var recipients = _emailErrorDefaultRecipients; 
      var subject = "ERROR: Failed To Create Directories in " + this.ToString() + " path: " + path; 
      var errorMessage = Error.BuildErrorMessage(ex, subject); 
      Email.SendMail(recipients, subject, errorMessage); 
      Console.WriteLine(errorMessage); 
      return false; 

     } 

    } 
0

Câu trả lời trước không xử lý Đường dẫn mạng. Mã được đính kèm cũng xử lý điều đó.

/// <summary> 
/// tests (and creates missing) directories in path containing many 
subDirectories which might not exist. 
    /// </summary> 
    /// <param name="FN"></param> 
    public static string VerifyPath(string FN, out bool AllOK) 
    { 
     AllOK = true; 
     var dir = FolderUtils.GetParent(FN); 
     if (!Directory.Exists(dir))//todo - move to folderUtils.TestFullDirectory 
     { 
      const char DIR = '\\'; 
      //string dirDel = "" + DIR; 

      string[] subDirs = FN.Split(DIR); 
      string dir2Check = ""; 
      int startFrom = 1;//skip "c:\" 
      FN = CleanPathFromDoubleSlashes(FN); 
      if (FN.StartsWith("" + DIR + DIR))//netPath 
       startFrom = 3;//FN.IndexOf(DIR, 2);//skip first two slashes.. 
      for (int i = 0; i < startFrom; i++) 
       dir2Check += subDirs[i] + DIR;//fill in begining 

      for (int i = startFrom; i < subDirs.Length - 1; i++)//-1 for the file name.. 
      { 
       dir2Check += subDirs[i] + DIR; 
       if (!Directory.Exists(dir2Check)) 
        try 
        { 
         Directory.CreateDirectory(dir2Check); 
        } 
        catch { AllOK = false; } 
      } 
     } 
     if (File.Exists(FN)) 
      FN = FolderUtils.getFirstNonExistingPath(FN); 
     if (FN.EndsWith("\\") && !Directory.Exists(FN)) 
      try { Directory.CreateDirectory(FN); } 
      catch 
      { 
       HLogger.HandleMesssage("couldn't create dir:" + FN, TypeOfExceptions.error, PartsOfSW.FileStructure); 
       AllOK = false; 
      } 

     return FN; 

    } 

Và "CleanDoubleSlashes chức năng":

public static string CleanPathFromDoubleSlashes(string basePath) 
    { 
     if (string.IsNullOrEmpty(basePath) || basePath.Length < 2)//don't clean first \\ of LAN address 
      return basePath; 
     for (int i = basePath.Length - 1; i > 1; i--) 
     { 
      if ((basePath[i] == '\\' && basePath[i - 1] == '\\') || (basePath[i] == '/' && basePath[i - 1] == '/')) 
      { 
       basePath = basePath.Remove(i, 1);//Substring(0, i - 2) + basePath.Substring(i, basePath.Length - 1 - i); 
      } 
     } 
     return basePath; 
    } 
Các vấn đề liên quan