【发布时间】:2012-06-01 15:56:12
【问题描述】:
我以为我通过关闭和处置我的阅读器解决了这个问题,但在某些情况下该文件仍在使用中。接下来我调用了垃圾收集器,因此文件将被释放。 这解决了 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();
}
Finish 在处理文件内容的大进程之后调用。
当我处理一个只有 1 行(或很少)行的文件时,我有时会收到此错误。似乎 windows 很快,DeleteFile(); 失败了。
我很难重现此错误,但有时它会连续发生两次。
当我处理需要超过 2 秒的文件时,这种情况永远不会发生。
我不能使用 using ,因为文件可以是 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();
【问题讨论】:
-
您不需要调用 GC.Collect。您不应该这样做,而且它应该不会影响删除文件的能力。
-
访问文件的代码是什么样的?如果我们能看到它,我们可以在那里提出更好的建议。
-
我们需要查看您用于创建、与之交互、和删除这些文件的所有代码。您可能在某处泄漏了一个对象,或者两个线程同时与同一个文件进行交互。
-
@ChrisShain 如果我泄漏了一个对象,我认为错误应该是随之而来的。病毒扫描程序/索引器/任何持有文件被锁定以供删除的东西是不是有可能?
-
@Joe 你能解释一下为什么我不应该打电话给 GC.Collect 吗?
标签: c# file-in-use