[英]C# Reuse StreamWriter or FileStream but change destination file
一點背景...
我將要描述的直到實現 StreamWriter 的所有內容都是我無法更改的業務流程。
每個月我都會將大約 200 個不同的數據表提取到單獨的文件中。 每個文件包含大約 400,000 行業務邏輯詳細信息,用於超過 5,000-6,000 個不同的業務單元。
為了通過手頭的工具有效地使用這些數據,我必須將這些文件分解為每個業務部門的單獨文件......
每個文件 200 個文件 x 5000 個業務單位 = 100,000 個不同的文件。
我一直在做的方式是典型的 StreamWriter 循環......
foreach(string SplitFile in List<BusinessFiles>)
{
using (StreamWriter SW = new StreamWriter(SplitFile))
{
foreach(var BL in g)
{
string[] Split1 = BL.Split(',');
SW.WriteLine("{0,-8}{1,-8}{2,-8}{3,-8}{4,-8}{5,-8}{6,-8}{7,-8}{8,-8}{9,-16}{10,-1}",
Split1[0], Split1[1], Split1[2], Split1[3], Split1[4], Split1[5], Split1[6], Split1[7], Split1[8], Convert.ToDateTime(Split1[9]).ToString("dd-MMM-yyyy"), Split1[10]);
}
}
}
這樣做的問題是,它需要過多的時間。 比如,有時處理所有文件可能需要 20 分鍾。
分析我的代碼顯示,98% 的時間都花在了程序離開循環后系統處理 StreamWriter 上。
所以我的問題是......
有沒有辦法保持底層 Stream 打開並重用它來編寫不同的文件?
我知道我可以 Flush() Stream 但我不知道如何讓它開始完全寫入另一個文件。 我似乎找不到無需調用另一個 StreamWriter 即可更改目標文件名的方法。
編輯:
這聽起來很對。 20 分鍾內 100,000 個文件超過每秒 83 個文件。 磁盤 I/O 幾乎是您在單台計算機中可以做的最慢的事情。 Dispose()
方法中的所有時間都是在關閉文件時等待緩沖區刷新到磁盤...這是將數據寫入持久存儲的實際時間,並且每個文件的單獨using
塊是正確的方法以確保安全完成。
為了加快速度,很想看看異步處理(async/await),但我認為你不會在那里找到任何收獲; 歸根結底,這是一個 I/O 密集型任務,因此針對 CPU 調度進行優化甚至可能使事情變得更糟。 如果您可以將 output 更改為寫入單個(索引)文件,則可以獲得更好的收益,因此操作系統的磁盤緩沖機制可以更有效。
回答您的問題,您有一個選項(在構造函數上添加一個標志),但它與垃圾收集器密切相關,還要考慮多線程環境,它可能會一團糟。 也就是說這是重載的構造函數:
StreamWriter(流,編碼,Int32,布爾值)
使用指定的編碼和緩沖區大小為指定的 stream 初始化 StreamWriter class 的新實例,並可選擇將 stream 保持打開狀態。
public StreamWriter (System.IO.Stream stream, System.Text.Encoding? encoding = default, int bufferSize = -1, bool leaveOpen = true);
我同意 Joel 的觀點,時間主要是因為將數據寫入磁盤。 但是,我對並行 IO 會更樂觀一些,因為 SSD 比普通 HDD 能夠更好地處理更高的負載。 所以我會嘗試一些事情:
1.並行做事
將您的外循環更改為並行循環
Parallel.ForEach(
myBusinessFiles,
new ParallelOptions(){MaxDegreeOfParallelism = 2},
SplitFile => {
// Loop body
});
嘗試更改並行度以查看性能是否有所提高。 這假設數據是線程安全的。
2.嘗試寫入高速本地SSD
我假設您正在寫入網絡文件夾,這會增加一些額外的延遲,因此您可能會嘗試寫入本地磁盤。 如果您已經這樣做了,請考慮獲得更快的磁盤。 如果您之后需要將所有文件移動到網絡驅動器,您可能不會獲得任何東西,但它可以讓您了解您從網絡中獲得的懲罰。
3. 嘗試寫入 Zip 存檔
有zip 檔案可以在其中包含多個文件,同時仍然允許相當容易地訪問單個文件。 這可以通過以下幾種方式幫助提高性能:
您也可以嘗試將每個文件保存在單獨的 zip 存檔中,但這樣您將主要從壓縮中受益。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.