如何加快FileStream的创建速度

wvl*_*zen 10 c# performance filestream

我的应用程序需要打开很多小文件,比如1440个文件,每个文件包含1分钟的数据,以读取某一天的所有数据.每个文件只有几个KB大.这是一个GUI应用程序,所以我希望用户(==我!)不必等待太长时间.

事实证明打开文件相当慢.经过研究,大多数时间都浪费在为每个文件创建FileStream(OpenStream = new FileStream).示例代码:

// stream en reader aanmaken
FileStream OpenStream;
BinaryReader bReader;

foreach (string file in files)
{
    // bestaat de file? dan inlezen en opslaan
    if (System.IO.File.Exists(file))
    {
        long Start = sw.ElapsedMilliseconds;

        // file read only openen, anders kan de applicatie crashen
        OpenStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

        Tijden.Add(sw.ElapsedMilliseconds - Start);

        bReader = new BinaryReader(OpenStream);

        // alles in één keer inlezen, werkt goed en snel
        // -bijhouden of appenden nog wel mogelijk is, zonodig niet meer appenden
        blAppend &= Bestanden.Add(file, bReader.ReadBytes((int)OpenStream.Length), blAppend);

        // file sluiten
        bReader.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用秒表计时器,我发现大多数(> 80%)的时间花在为每个文件创建FileStream上.创建BinaryReader并实际读取文件(Bestanden.add)几乎没有时间.

我对此感到困惑,无法找到加快速度的方法.我该怎么做才能加快FileStream的创建速度?

更新问题:

  • 在Windows 7和Windows 10上都会发生这种情况
  • 文件是本地的(在SSD磁盘上)
  • 目录中只有1440个文件
  • 奇怪的是,稍后再次读取(相同)文件,创建FileStreams突然几乎没有时间.操作系统在某处记住文件流.
  • 即使我关闭应用程序并重新启动它,"再次"打开文件也几乎没有时间.这使得很难找到性能问题.我不得不制作很多目录副本来反复重新创建问题.

Iva*_* R. 2

正如您在问题的评论中提到的,FileStream通过创建对象读取第一个 4K 来缓冲。您可以更改此缓冲区的大小以反映更好的数据大小。(例如,如果您的文件小于缓冲区,则减少)。如果你按顺序读取文件,你可以通过 给操作系统提示FileOptions。此外,您可以避免BinaryReader,因为您完全读取文件。

\n\n
    // stream en reader aanmaken\n    FileStream OpenStream;\n\n    foreach (string file in files)\n    {\n        // bestaat de file? dan inlezen en opslaan\n        if (System.IO.File.Exists(file))\n        {\n            long Start = sw.ElapsedMilliseconds;\n\n            // file read only openen, anders kan de applicatie crashen\n            OpenStream = new FileStream(\n                file,\n                FileMode.Open,\n                FileAccess.Read,\n                FileShare.ReadWrite,\n                bufferSize: 2048, //2K for example \n                options: FileOptions.SequentialScan);\n\n            Tijden.Add(sw.ElapsedMilliseconds - Start);\n\n            var bufferLenght = (int)OpenStream.Length;\n            var buffer = new byte[bufferLenght];\n            OpenStream.Read(buffer, 0, bufferLenght);\n\n            // alles in \xc3\xa9\xc3\xa9n keer inlezen, werkt goed en snel\n            // -bijhouden of appenden nog wel mogelijk is, zonodig niet meer appenden\n            blAppend &= Bestanden.Add(file, buffer, blAppend);\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不知道Bestanden对象的类型。但是,如果该对象具有从数组读取的方法,您还可以重用文件缓冲区。

\n\n
    //the buffer should be bigger than the biggest file to read\n    var bufferLenght = 8192;\n    var buffer = new byte[bufferLenght];\n\n    foreach (string file in files)\n    {\n        //skip \n        ...\n        var fileLenght = (int)OpenStream.Length;\n        OpenStream.Read(buffer, 0, fileLenght);\n\n        blAppend &= Bestanden.Add(file, /*read bytes from buffer */, blAppend);\n
Run Code Online (Sandbox Code Playgroud)\n\n

我希望它有帮助。

\n