该进程无法访问该文件,因为它在删除时正被另一个进程使用
本文关键字:进程 另一个 删除 访问 文件 因为 | 更新日期: 2023-09-27 18:35:49
我以为我通过关闭和处置我的阅读器解决了这个问题,但在某些情况下文件仍在使用中。接下来,我调用了垃圾收集器,因此将释放该文件。这解决了99%会导致此错误的所有问题。使用的代码:
public override void Finish()
{
// Kill the reader!
if (_reader != null)
{
_reader.Close();
_reader.Dispose();
// Make sure the server doesn't hold the file
GC.Collect();
}
DeleteFile();
}
完成是在处理文件内容的大进程之后调用的。
当我处理只有 1 行(或很少)行的文件时,有时会收到此错误。似乎窗口正在快速,DeleteFile();
失败。我很难重现此错误,但有时它只是连续发生两次。
当我处理处理文件需要超过 2 秒的时间时,这永远不会发生。
我不能使用,因为文件可以是GB的,当它的内存太满时,Windows不喜欢它。此外,通过这种方式,该过程执行得更好。
问题:
我还能做些什么来防止此错误吗?
PS:随时询问更多信息。
编辑:
删除文件的代码
protected void DeleteFile()
{
// Delete the file
if (FileName != null && File.Exists(FileName))
File.Delete(FileName);
}
用于创建文件的代码
protected void WriteFile()
{
// Prepare variables
string path = Path.GetTempPath();
path += "''MyTempFile";
// Modifiy path to avoid overwriting an existing file.
path += ".csv";
// Write the file to the temp folder
using (FileStream fs = new FileStream(path, FileMode.Create))
{
fs.Write(MyFile, 0, MyFile.Length);
}
// Was the writing successfully completed?
_FileName = File.Exists(path) ? path : null;
}
用于创建读取器的代码
protected override void ReadFile()
{
if (FileName == null)
WriteFile();
// Read the lines
_reader = new StreamReader(FileName, Encoding.Default, true);
while (_reader.Peek() != -1)
{
TotalRows++;
_reader.ReadLine();
}
// Read the lines
_reader = new StreamReader(FileName, Encoding.Default, true);
}
我使用抽象类来确定应该如何读取输入。通过以下语句,我将遍历文件的内容。
while (FileReader.NextRow(out currentRow, out currentRowNumber))
{
// Process current Row...
}
方法NextRow()看起来像这样
public override bool NextRow(out List<object> nextRow, out int rowNumber)
{
if (RowNumber > TotalRows)
{
nextRow = null;
rowNumber = 0;
return false;
}
// Set the row number to return
rowNumber = RowNumber;
// Prepare the row
nextRow = _reader.ReadLine().ExtensionThatProcessesTheRow();
RowNumber++;
return true;
}
while 循环关闭后,我调用完成过程。 FileReader.Finish();
正如您所说,它只是偶尔发生,可能只是锁被按住,如果您进行检查,那么希望如果在您进行另一次检查时它失败,那么它应该有时间摆脱缓存的锁。如果您使用这样的方法来检查文件是否仍在使用中:
public bool CheckIfFileIsBeingUsed(string fileName){
try{
File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (Exception exp){
return true;
}
return false;
}
如果它返回 false,则继续删除该文件,其他明智的等待,然后再次运行检查。
注意:这可能应该是一个评论,但我需要额外的空间。
此代码没有意义:
// Prepare variables
string path = Path.GetTempPath();
// Write the file to the temp folder
using (FileStream fs = new FileStream(path, FileMode.Create))
路径是临时文件的目录。 您不应该能够创建具有该名称的文件。
此外,这里使用一个名为 文件名 的变量:
protected void DeleteFile()
{
// Delete the file
if (FileName != null && File.Exists(FileName))
File.Delete(FileName);
}
但在 WriteFile 中,您使用的是一个名为 _FileName 的变量:
// Was the writing successfully completed?
_FileName = File.Exists(path) ? path : null;
基于上述情况,我的猜测是,你没有写你认为你在写的东西,或者没有删除你认为你正在删除的东西。
我想我发现了问题...
在 ReadFile()
中重置之前,此阅读器未被处理。
_reader = new StreamReader(FileName, Encoding.Default, true);
while (_reader.Peek() != -1)
{
TotalRows++;
_reader.ReadLine();
}
我把它改成了。
using (var reader = new StreamReader(FileName, Encoding.Default, detectEncodingFromByteOrderMarks: true))
{
while (reader.Peek() != -1)
{
TotalRows++;
reader.ReadLine();
}
}