Tệp đang được sử dụng bởi một quy trình khác sau khi sử dụng File.Create ()


117

Tôi đang cố gắng phát hiện nếu một tập tin tồn tại trong thời gian chạy, nếu không, hãy tạo nó. Tuy nhiên tôi đang gặp lỗi này khi tôi cố gắng viết nó:

Quá trình không thể truy cập tệp 'myfile.ext' vì nó đang được sử dụng bởi một quy trình khác.

string filePath = string.Format(@"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre); 
if (!File.Exists(filePath)) 
{ 
    File.Create(filePath); 
} 

using (StreamWriter sw = File.AppendText(filePath)) 
{ 
    //write my text 
}

Vài ý kiến ​​về việc làm thế nào đê sửa nó?

Câu trả lời:


112

Các File.Createphương pháp tạo ra các tập tin và mở ra một FileStreamvào tệp. Vì vậy, tập tin của bạn đã được mở. Bạn thực sự không cần phương thức file. Tạo ra tất cả:

string filePath = @"c:\somefilename.txt";
using (StreamWriter sw = new StreamWriter(filePath, true))
{
    //write to the file
}

Boolean trong hàm StreamWritertạo sẽ khiến nội dung được nối thêm nếu tệp tồn tại.


Tôi đã thử đoạn mã trên nhưng tôi gặp lỗi tương tự khi tệp được tạo và khi nó cố ghi vào tệp thì nó hiển thị tệp đang được sử dụng bởi quy trình khác.
Anmol Rathod

@AnmolRathod hãy chắc chắn rằng bạn không sử dụng File.Create()phương pháp! Đoạn mã trên đã tạo tệp!
Daniel Eisenreich

138
    File.Create(FilePath).Close();
    File.WriteAllText(FileText);

Tôi muốn cập nhật câu trả lời này để nói rằng đây không thực sự là cách hiệu quả nhất để viết tất cả văn bản. Bạn chỉ nên sử dụng mã này nếu bạn cần một cái gì đó nhanh chóng và bẩn thỉu.

Tôi là một lập trình viên trẻ khi tôi trả lời câu hỏi này, và lúc đó tôi nghĩ tôi là một thiên tài vì đã đưa ra câu trả lời này.


4
Tôi thích cách tất cả các câu trả lời khác quá phức tạp. Mọi người không nhận ra rằng có một câu trả lời đơn giản hơn cho mọi vấn đề.
Carsen Daniel Yates

14
Nhược điểm của mã này là nó không cần thiết mở tệp hai lần. Ngoài ra, thực sự không cần thiết phải kiểm tra xem tệp có tồn tại hay không, vì hàm tạo FileStream sẽ tự động tạo tệp cho bạn nếu nó không tồn tại, trừ khi bạn nói rõ ràng là không làm điều đó.
đăng lại

2
@reirab Điều này hoàn toàn tương đối. Tôi cần kiểm tra xem tập tin có tồn tại không và nếu có, hãy xóa nó và tạo lại nó, vì vậy câu trả lời này được ưu tiên trong trường hợp của tôi.
makoshichi

1
@SO Sau đó, bạn có một vấn đề khác với OP, chỉ là một vấn đề liên quan. Ngoài ra, trong trường hợp của bạn, bạn vẫn có thể chỉ sử dụng hàm FileStream(string, FileMode)tạo và truyền nó FileMode.Create , sẽ ghi đè lên bất kỳ tệp hiện có nào. Vẫn không cần phải mở tập tin hai lần. Ngoài ra, câu trả lời này đã được chỉnh sửa sau khi tôi đăng bình luận ban đầu của mình.
thiệu lại vào

2
Điểm của câu trả lời này là cho thấy bạn chỉ có thể thêm .Close()vào cuối, vì vậy nó hoạt động trong mọi trường hợp. Tôi không tin hệ thống sử dụng FileStreamcho tất cả mọi thứ vì tôi không muốn ngoại lệ xảy ra với FileMode.Createviệc tệp đã có sẵn - đặc biệt là khi tôi muốn xóa nội dung và không thêm vào chúng FileMode.Open. Đối với tôi, FileStreamchỉ thực sự hoạt động sau khi loại bỏ các tập tin trong câu hỏi, sau đó viết cho nó. Vì File.Createđể nó mở và khóa, có vẻ như thêm .Close()vào đó là cách thực sự duy nhất để đối phó với kịch bản của tôi và SO.
vapcguy

25

Khi tạo tệp văn bản, bạn có thể sử dụng mã sau:

System.IO.File.WriteAllText("c:\test.txt", "all of your content here");

Sử dụng mã từ bình luận của bạn. Tập tin (luồng) bạn tạo phải được đóng lại. File.Create trả lại filestream cho tệp vừa tạo:

string filePath = "filepath here";
if (!System.IO.File.Exists(filePath))
{
    System.IO.FileStream f = System.IO.File.Create(filePath);
    f.Close();
}
using (System.IO.StreamWriter sw = System.IO.File.AppendText(filePath))
{ 
    //write my text 
}

Tôi dường như không có một lựa chọn gần gũi. Đây là mã: string filePath = string.Format (@ "{0} \ M {1} .dat", ConfigurationManager.AppSinstall ["DirectoryPath"], costCentre); if (! File.Exists (filePath)) {File.Create (filePath); } bằng cách sử dụng (StreamWriter sw = File.AppendText (filePath)) {// viết văn bản của tôi}
Brett

File.Createtrả lại FileStreamvà đó làClose()
Null Head

15
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();

7
Chào mừng bạn đến với Stackoverflow. Ít nhất bạn nên viết mô tả ngắn để mô tả câu trả lời / giải pháp của bạn.
Paresh Mayani 17/03/2016

9

File.Create trả về một FileStream. Bạn cần phải đóng nó khi bạn đã ghi vào tệp:

using (FileStream fs = File.Create(path, 1024)) 
        {
            Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
            // Add some information to the file.
            fs.Write(info, 0, info.Length);
        }

Bạn có thể sử dụng để tự động đóng tệp.


Mặc dù OP đang cố gắng để mở một StreamWriternhư có thể được suy ra từ việc sử dụng của mình File.AppendText.
binki

8

Tôi đã cập nhật câu hỏi của bạn với đoạn mã. Sau khi thụt lề đúng cách, ngay lập tức rõ ràng vấn đề là gì: bạn sử dụng File.Create()nhưng không đóng cái FileStreammà nó trả lại.

Làm theo cách đó là không cần thiết, StreamWriterđã cho phép nối thêm vào tệp hiện có tạo tệp mới nếu nó chưa tồn tại. Như thế này:

  string filePath = string.Format(@"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre); 
  using (StreamWriter sw = new StreamWriter(filePath, true)) {
    //write my text 
  }

Mà sử dụng constructor nàyStreamWriter .


1

Câu hỏi này đã được trả lời, nhưng đây là một giải pháp trong thế giới thực, kiểm tra xem thư mục có tồn tại không và thêm một số vào cuối nếu tệp văn bản tồn tại. Tôi sử dụng điều này để tạo các tệp nhật ký hàng ngày trên một dịch vụ Windows mà tôi đã viết. Tôi hi vọng điêu nay se giup được ai đo.

// How to create a log file with a sortable date and add numbering to it if it already exists.
public void CreateLogFile()
{
    // filePath usually comes from the App.config file. I've written the value explicitly here for demo purposes.
    var filePath = "C:\\Logs";

    // Append a backslash if one is not present at the end of the file path.
    if (!filePath.EndsWith("\\"))
    {
        filePath += "\\";
    }

    // Create the path if it doesn't exist.
    if (!Directory.Exists(filePath))
    {
        Directory.CreateDirectory(filePath);
    }

    // Create the file name with a calendar sortable date on the end.
    var now = DateTime.Now;
    filePath += string.Format("Daily Log [{0}-{1}-{2}].txt", now.Year, now.Month, now.Day);

    // Check if the file that is about to be created already exists. If so, append a number to the end.
    if (File.Exists(filePath))
    {
        var counter = 1;
        filePath = filePath.Replace(".txt", " (" + counter + ").txt");
        while (File.Exists(filePath))
        {
            filePath = filePath.Replace("(" + counter + ").txt", "(" + (counter + 1) + ").txt");
            counter++;
        }
    }

    // Note that after the file is created, the file stream is still open. It needs to be closed
    // once it is created if other methods need to access it.
    using (var file = File.Create(filePath))
    {
        file.Close();
    }
}

1

Tôi biết đây là một câu hỏi cũ, nhưng tôi chỉ muốn ném nó ra khỏi đó mà bạn vẫn có thể sử dụng File.Create("filename")", chỉ cần thêm .Dispose()vào nó.

File.Create("filename").Dispose();

Bằng cách này, nó tạo và đóng tệp cho quá trình tiếp theo để sử dụng nó.


1
File.Create(FilePath).Close();từ câu trả lời ở trên có this.Dispose(true); GC.SuppressFinalize((object) this);trong việc thực hiện của nó.
Ghukas

1

Tôi nghĩ rằng tôi biết lý do cho ngoại lệ này. Bạn có thể đang chạy đoạn mã này trong nhiều luồng.


Đối với tôi là vấn đề mà tôi viết một tập tin đăng nhập trên asyncron cách (trong một chủ đề khác nhau:. Task.Run () mà không cần chờ (có mục đích), và nguyên nhân này multithread quyền truy cập vào cùng một tập tin
Bence Végert

-1

Hãy thử điều này: Nó hoạt động trong mọi trường hợp, nếu tệp không tồn tại, nó sẽ tạo nó và sau đó ghi vào nó. Và nếu đã tồn tại, không có vấn đề gì nó sẽ mở và viết cho nó:

using (FileStream fs= new FileStream(@"File.txt",FileMode.Create,FileAccess.ReadWrite))
{ 
     fs.close();
}
using (StreamWriter sw = new StreamWriter(@"File.txt")) 
 { 
    sw.WriteLine("bla bla bla"); 
    sw.Close(); 
 } 

1
sử dụng sẽ đóng tập tin bằng cách gọi Vứt bỏ. Trong tệp mẫu của bạn đã bị đóng hai lần
Valentine Zakharenko
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.