【发布时间】:2017-12-13 05:17:28
【问题描述】:
我的应用程序需要打开很多小文件,比如 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();
}
}
使用秒表计时器,我发现大部分(> 80%)时间都花在为每个文件创建 FileStream 上。创建 BinaryReader 并实际读取文件 (Bestanden.add) 几乎不需要任何时间。
我对此感到困惑,无法找到加快速度的方法。如何加快 FileStream 的创建速度?
更新问题:
- Windows 7 和 Windows 10 都会发生这种情况
- 文件是本地的(在 SSD 磁盘上)
- 一个目录只有1440个文件
- 奇怪的是,稍后再次读取(相同的)文件,突然创建 FileStreams 几乎没有花费任何时间。操作系统所在的某个地方 记住文件流。
- 即使我关闭应用程序并重新启动它,“再次”打开文件也几乎不会花费任何时间。这使得它很难找到 性能问题。我不得不制作很多目录副本 一遍又一遍地重现问题。
【问题讨论】:
-
似乎是一个可能的操作系统问题。您访问的是什么类型的操作系统?它是本地的还是网络上的(关闭运行应用程序的电脑)?目录是否包含其他文件(即 windows 对每个目录的文件数有建议限制)。
-
这在 windows 7 和 windows 10 上都存在。这些文件位于仅包含这 1440 个文件的目录中。我刚刚意识到我忘了提到一些东西: - 我第一次想读取文件时它很慢 - 如果我再次从应用程序读取文件,创建 FileStreams 突然几乎没有时间(这怎么可能?是操作系统记得文件句柄吗?我的应用程序当然不是)。 - 如果我关闭应用程序并重新开始,再次读取相同的文件几乎不需要任何时间。操作系统中必须有某种缓冲/内存。
-
你试过File.RealAllBytes吗?
-
我刚刚使用 File.ReadAllBytes 进行了测试,并且行为是相同的(除了您无法再看到延迟的确切来源)。再次读取文件也几乎不花时间。
-
Windows 确实将文件缓存在内存中,因此更快的后续访问并不令人意外。您可以使用technet.microsoft.com/en-us/sysinternals/ff700229.aspx清除待机列表
标签: c# performance filestream