[英]How to speed up creation of a 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();
}
}
使用秒表计时器,我发现大多数(> 80%)的时间花在为每个文件创建FileStream上。 创建BinaryReader并实际读取文件(Bestanden.add)几乎没有时间。
我对此感到困惑,无法找到加快速度的方法。 我该怎么做才能加快FileStream的创建速度?
更新问题:
正如您在问题的评论中提到的, FileStream
通过创建对象将第一个4K读取为缓冲区。 您可以更改此缓冲区的大小以反映更好的数据大小。 (例如,如果文件小于缓冲区,则减少)。 如果按顺序读取文件,则可以通过FileOptions
为OS提供有关此内容的提示。 此外,您可以避免使用BinaryReader
,因为您完全读取文件。
// stream en reader aanmaken
FileStream OpenStream;
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,
bufferSize: 2048, //2K for example
options: FileOptions.SequentialScan);
Tijden.Add(sw.ElapsedMilliseconds - Start);
var bufferLenght = (int)OpenStream.Length;
var buffer = new byte[bufferLenght];
OpenStream.Read(buffer, 0, bufferLenght);
// alles in één keer inlezen, werkt goed en snel
// -bijhouden of appenden nog wel mogelijk is, zonodig niet meer appenden
blAppend &= Bestanden.Add(file, buffer, blAppend);
}
}
我不知道Bestanden
对象的类型。 但是,如果此对象具有从数组中读取的方法,则还可以为文件重用缓冲区。
//the buffer should be bigger than the biggest file to read
var bufferLenght = 8192;
var buffer = new byte[bufferLenght];
foreach (string file in files)
{
//skip
...
var fileLenght = (int)OpenStream.Length;
OpenStream.Read(buffer, 0, fileLenght);
blAppend &= Bestanden.Add(file, /*read bytes from buffer */, blAppend);
我希望它有所帮助。
免责声明:这个答案只是一个(成熟的)推测,它是一个Windows错误,而不是你可以用不同的代码修复的东西。
所以这种行为可能与这里描述的Windows错误有关: “24核CPU,我无法移动我的鼠标” 。
这些进程都是从NtGdiCloseProcess中释放锁。
因此,如果FileStream
在操作系统中使用并保持这样一个关键锁定,那么它将等待几个μSecs用于每个文件,这将增加数千个文件。 它可能是一个不同的锁,但上面提到的错误至少增加了类似问题的可能性。
为了证明或反驳这个假设,有必要深入了解内核的内部工作原理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.