流关闭后文件保持锁定状态

时间:2014-01-02 14:34:06

标签: c# .net

我有一些代码尝试从可能加密或未加密的文件中读取。如果它是加密的,那么它在实际数据之前有一个包含几个字节信息的头。访问文件的逻辑如下:

bool encrypted = IsEncryptedFile(fileName);
Stream s = null;

if (encrypted)
{
    s = new EncryptedStreamReader(fileName);
}
else
{
    s = new StreamReader(fileName);
}

// Read from s

在极少数情况下(例如,10000个文件中的一个文件),我在尝试创建流阅读器时收到错误“进程无法访问文件xxx,因为它正由另一个进程使用”。 IsEncryptedFile方法打开文件以读取标头(如果存在),并且没有其他代码访问该文件。该方法总是关闭文件(它在using语句中打开),它总是成功。

我假设关闭.NET流并不能保证关闭底层操作系统句柄并添加代码以等待并在一段时间后重试。这会降低发生错误的频率,但偶尔也会发生错误。

我的问题是:

我的假设是正确的,关闭然后立即打开文件的代码可能会收到此错误,因为Windows仍在释放它,即使.NET Stream.Close方法调用已返回(或退出使用块)?

与延长我的重试间隔相比,是否有更少的垃圾处理方式?

修改

IsEncryptedFile执行此操作

private bool IsEncryptedFile(string fileName)
{
    using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        //Read header from fileStream
        //Returns true if encrypted else false
    }
}

由于显而易见的原因,我没有包含实际的逻辑,但无论如何它都是无关紧要的,因为您需要知道的是总是关闭的流(使用语句)。

没有多线程问题。我的代码中没有其他部分访问该文件。每个文件只调用一次该方法。 “从s读取”中发生的事情并不重要,因为此时文件已被打开(OK - 9999次,10000次)或未打开(坏 - 1次10000次)。

1 个答案:

答案 0 :(得分:1)

确保使用使用尝试最终子句正确处理流。

此外,您可以使用 FileStream 设置文件访问选项。

例:

bool encrypted = IsEncryptedFile(fileName);
Stream s = null;
try
{
    if (encrypted)
    {
        s = new EncryptedStreamReader(fileName);
    }
    else
    {
        s = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    }

    // Read from s
}
finally
{
    if (s != null)
        s.Close();
}

检查打开流的所有方法(例如 IsEncryptedFile ),以确保正确关闭所有流。