使用 File.Create() 后被另一个进程使用的文件

Posted

技术标签:

【中文标题】使用 File.Create() 后被另一个进程使用的文件【英文标题】:File being used by another process after using File.Create() 【发布时间】:2011-02-16 09:42:09 【问题描述】:

我正在尝试在运行时检测文件是否存在,如果不存在,请创建它。但是,当我尝试写入时出现此错误:

该进程无法访问文件“myfile.ext”,因为它正被另一个进程使用。

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

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

关于如何解决它的任何想法?

【问题讨论】:

【参考方案1】:
    File.Create(FilePath).Close();
    File.WriteAllText(FileText);

我想更新这个答案,说这并不是编写所有文本的最有效方式。 只有在需要快速而肮脏的东西时才应该使用此代码。

当我回答这个问题时,我还是一个年轻的程序员,当时我认为自己是某种天才,能得出这个答案。

【讨论】:

我喜欢所有其他答案都太复杂了。人们没有意识到每个问题都有一个更简单的答案。 此代码的缺点是它不必要地打开文件两次。此外,根本不需要检查文件是否存在,因为如果文件不存在,FileStream 构造函数会自动为您创建它,除非您明确告诉它不要这样做。 @reirab 这完全是相对的。我需要检查文件是否存在,如果存在,请将其删除并重新创建,因此在我的情况下,此答案是首选。 @S.O.然后你有一个与 OP 不同的问题,只是一个相关的问题。此外,在您的情况下,您仍然可以只使用FileStream(string, FileMode) 构造函数并将其传递给FileMode.Create,这将覆盖任何现有文件。仍然不需要打开文件两次。另外,这个答案是在我发表原始评论后编辑的。 这个答案的重点是表明您可以在末尾添加.Close(),因此它在任何情况下都有效。我不信任对所有内容都使用FileStream 的系统,因为我不希望在FileMode.Create 上发生文件已经存在的异常——尤其是当我想清除内容而不是通过FileMode.Open 附加到它们时。对我来说,FileStream 只有在删除有问题的文件之后才真正起作用,然后写入它。由于File.Create 将其打开并锁定,似乎将.Close() 添加到它是处理我的场景和S.O. 的唯一真正方法。【参考方案2】:

File.Create 方法创建文件并在文件上打开FileStream。所以你的文件已经打开了。你根本不需要 file.Create 方法:

string filePath = @"c:\somefilename.txt";
using (StreamWriter sw = new StreamWriter(filePath, true))

    //write to the file

如果文件存在,StreamWriter 构造函数中的布尔值将导致附加内容。

【讨论】:

我尝试了上面的代码,但是在创建文件时遇到了同样的错误,当它尝试写入文件时,它显示文件正在被其他进程使用。 @AnmolRathod 确保你不要使用File.Create() 方法!上面的 sn -p 已经创建了文件!【参考方案3】:

创建文本文件时可以使用以下代码:

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

使用您评论中的代码。您创建的文件(流)必须关闭。 File.Create 将文件流返回到刚刚创建的文件。:

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 

【讨论】:

我似乎没有关闭选项。代码如下: string filePath = string.Format(@"0\M1.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre); if (!File.Exists(filePath)) File.Create(filePath); using (StreamWriter sw = File.AppendText(filePath)) //写我的文本 File.Create 返回FileStream 并且有Close()【参考方案4】:
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();

【讨论】:

欢迎来到 ***。你至少应该写简短的描述来描述你的答案/解决方案。【参考方案5】:

File.Create 返回一个 FileStream。写入文件后需要关闭它:

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);
        

您可以使用 using 自动关闭文件。

【讨论】:

虽然 OP 正试图打开一个 StreamWriter,这可以从他对 File.AppendText 的使用中推断出来。【参考方案6】:

我用代码 sn-p 更新了您的问题。适当缩进后,问题就很明显了:你使用了File.Create(),但没有关闭它返回的FileStream

这样做是不必要的,StreamWriter 已经允许附加到现有文件如果它尚不存在则创建一个新文件。像这样:

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

其中使用this StreamWriter constructor。

【讨论】:

【参考方案7】:

我知道这是一个老问题,但我只是想把它扔在那里,你仍然可以使用File.Create("filename")",只需将.Dispose() 添加到它。

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

这样它会创建并关闭文件以供下一个进程使用。

【讨论】:

File.Create(FilePath).Close(); 从上面的答案有 this.Dispose(true); GC.SuppressFinalize((object) this); 在其实现中。【参考方案8】:

这个问题已经得到解答,但这里有一个现实世界的解决方案 检查目录是否存在,如果是文本文件,则在末尾添加一个数字 存在。我使用它在我编写的 Windows 服务上创建每日日志文件。一世 希望这对某人有所帮助。

// 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();
    

【讨论】:

【参考方案9】:

我想我知道这个例外的原因。您可能在多个线程中运行此代码 sn-p。

【讨论】:

对我来说,问题是我以异步方式编写日志文件(在不同的线程中:Task.Run() 无需等待(故意),这会导致多线程访问同一文件。 【参考方案10】:

试试这个:它在任何情况下都有效,如果文件不存在,它会创建它然后写入它。如果已经存在,它会打开并写入它没问题:

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(); 
  

【讨论】:

使用将通过调用 Dispose 关闭文件。在您的示例文件中被关闭了两次

以上是关于使用 File.Create() 后被另一个进程使用的文件的主要内容,如果未能解决你的问题,请参考以下文章

C# 使用File.Create方法创建文件时,报进程被占用

xmlDocument 已被另一个进程使用

该进程无法访问该文件,因为它正被另一个进程 Streamwriter 使用

dotnet publish 错误:该进程无法访问该文件,因为它正被另一个进程使用

System.IO.IOException: '该进程无法访问该文件,因为它正被另一个进程使用

该进程无法访问该文件,因为它正被另一个进程使用