[英]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.