使用 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方法创建文件时,报进程被占用
该进程无法访问该文件,因为它正被另一个进程 Streamwriter 使用
dotnet publish 错误:该进程无法访问该文件,因为它正被另一个进程使用