在非常大的文件流上处理速度慢?

时间:2014-08-10 07:04:45

标签: c# file-io

我已获得此代码

string archiveFileName = BuildArchiveFileName(i, null);
string tmpArchiveFileName = BuildArchiveFileName(i, "tmp");
try
{
    using (FileStream tmpArchiveMemoryStream = new FileStream(tmpArchiveFileName, FileMode.Create))
    {
        using (BinaryWriter pakWriter = new BinaryWriter(tmpArchiveMemoryStream))
        {
            if (i == 0)
            {
                WriteHeader(pakWriter, pakInfo.Header);
                WriteFileInfo(pakWriter, pakInfo.FileList);
                uint remainingBytesToDataOffset = pakInfo.Header.DataSectionOffset - CalculateHeaderBlockSize(pakInfo.Header);
                pakWriter.Write(Util.CreatePaddingByteArray((int)remainingBytesToDataOffset));
            }

            foreach (String file in pakInfo.FileList.Keys)
            {
                DosPak.Model.FileInfo info = pakInfo.FileList[file];
                if (info.IndexArchiveFile == i)
                {
                    //Console.WriteLine("Writing " + file);
                    byte[] fileData = GetFileAsStream(file, false);
                    int paddingSize = (int)CalculateFullByteBlockSize((uint)fileData.Length) - fileData.Length;
                    pakWriter.Write(fileData);
                    pakWriter.Write(Util.CreatePaddingByteArray(paddingSize));
                }
            }
        }
    }
}
finally
{
    File.Delete(archiveFileName);
    File.Move(tmpArchiveFileName, archiveFileName);
}

我已经使用NUnit对小文件大小进行了测试,它运行良好。然后,当我在一个真实的例子上尝试它时,这是超过1 GB的文件。我在删除方面遇到了麻烦。它声明该文件仍在被另一个进程使用。虽然它不应该在退出使用分支后处理该文件。因此,我想知道文件流的处理是否执行缓慢,这就是我遇到麻烦的原因。在我的所有文件处理中的小注释我使用带有using关键字的FileStream。

1 个答案:

答案 0 :(得分:4)

  

虽然退出使用分支后该文件不应该被处理

这不是抱怨的内容,您无法删除 archiveFileName 。正如异常消息所说,其他一些进程已打开文件。如果你不知道可能是什么进程,那么可以使用任务管理器的进程选项卡逐个删除它们。那是你自己的过程并不完全是不寻常的。最好的办法是与SysInternals'处理实用程序,它可以显示进程名称。

删除文件通常是多任务操作系统的危险冒险,总是非零赔率,其他一些进程也对文件感兴趣。他们应该用FileShare.Delete打开文件,但这经常被忽视。

最安全的方法是使用File.Replace()。第三个参数,备份文件名,是至关重要的,它允许重命名文件并继续存在,以便其他进程可以继续使用它。您应该尝试在代码的 start 中删除该备份文件。如果这不成功,那么File.Replace()也无法正常工作。但是,请先检查程序中是否存在错误,然后运行Handle实用程序。