使用File.Create()后,另一个进程正在使用该文件


117

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

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

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 
}

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

Answers:


112

File.Create方法创建文件并在文件上打开一个FileStream。因此,您的文件已经打开。您根本不需要file.Create方法:

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

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


我尝试了上面的代码,但是在创建文件时以及在尝试写入文件时出现相同的错误,表明文件正在由其他进程使用。
Anmol Rathod '18年

@AnmolRathod确保您不使用File.Create()方法!上面的代码段已经创建了文件!
Daniel Eisenreich '18

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

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

当我回答这个问题时,我还是一个年轻的程序员,那时我以为自己是个天才。


4
我喜欢所有其他答案都太复杂了。人们没有意识到对每个问题都有一个简单的答案。
卡森·丹尼尔·耶茨

14
该代码的缺点是它不必要地两次打开文件。另外,实际上根本不需要检查文件是否存在,因为如果文件流不存在,FileStream构造函数将自动为您创建文件,除非您明确指示不要这样做。
reirab 2013年

2
@reirab这是完全相对的。我需要检查文件是否存在,如果存在,请删除并重新创建它,因此在我的情况下,首选此答案。
makoshichi 2016年

1
@SO然后,您将遇到与OP不同的问题,只是一个相关的问题。同样,在您的情况下,您仍然可以只使用FileStream(string, FileMode)构造函数并将其传递给FileMode.Create,它将覆盖任何现有文件。仍然无需两次打开文件。另外,在我发表原始评论后,此答案已被编辑。
reirab '16

2
这个答案的重点是表明您可以.Close()在最后添加内容,因此无论如何都可以使用。我不信任FileStream任何使用的系统,因为我不想FileMode.Create在文件已经存在的情况下发生异常-尤其是当我要清除内容而不要通过它们追加内容时FileMode.Open。对我来说,FileStream只有删除了有问题的文件然后写入该文件后,它才真正起作用。由于File.Create将其保持打开和锁定状态,因此添加它似乎.Close()是处理我的方案和SO的唯一真实方法。
vapcguy

25

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

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} \ M {1} .dat”,ConfigurationManager.AppSettings [“ DirectoryPath”],costCentre); 如果(!File.Exists(filePath)){File.Create(filePath); }使用(StreamWriter sw = File.AppendText(filePath)){//写出我的文字}
Brett 2010年

File.Create返回FileStream并且具有Close()
Null Head

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

7
欢迎使用Stackoverflow。您至少应该写简短的描述来描述您的答案/解决方案。
Paresh Mayani 2014年

9

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正在尝试打开StreamWriteras,这可以从他对的使用中得出File.AppendText
宾基

8

我用代码片段更新了您的问题。适当缩进后,可以立即清楚问题所在:您使用File.Create()但不关闭FileStream返回的结果。

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

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

使用StreamWriter构造函数


1

这个问题已经被回答,但是这是一个实际的解决方案,它检查目录是否存在,如果文本文件存在,则在末尾添加一个数字。我用它在我编写的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();
    }
}

1

我知道这是一个古老的问题,但是我只想把它扔出去,仍然可以使用File.Create("filename")",只需添加.Dispose()它即可。

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

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


1
File.Create(FilePath).Close();从上面的答案有this.Dispose(true); GC.SuppressFinalize((object) this);其实施。
Ghukas

1

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


对我来说,是我以异步方式写日志文件的问题(在另一个线程中:Task.Run(),没有等待(故意),这导致对同一文件的多线程访问。)
BenceVégert,

-1

尝试以下操作:在任何情况下都可以使用,如果文件不存在,它将创建该文件然后写入该文件。如果已经存在,它将打开并写入它:

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
使用将通过调用Dispose关闭文件。在您的示例文件中,两次关闭
Valentine Zakharenko
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.