在伺服器端操作文字檔案的讀取總是令人擔心,因為是多人多工的環境,一不小心就會造成資源鎖死(死結)。舉例來說,如果你開啟一個文字檔案的方式錯誤,可能會造成其他執行緒 無法在你讀取檔案的當下,跟你一起分享這個檔案的讀取權限,這樣的設計會造成佇列的排隊,而如果被等候的執行緒剛好出了甚麼差錯,這下就是災難的開始了。
簡單的說,就是放棄寫入權限,並且依循Windows底層的檔案共享讀取機制,將檔案正確的設定共享讀取的權限,以防止咬檔的問題產生。程式碼如下:
using ( System.IO.StreamReader oSR = new System.IO.StreamReader ( new System.IO.FileStream ( cFilePathAndName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite ) )) { oSR.ReadToEnd(); }
透過這樣的方式,如果有其他的執行緒要一起進行這個文字檔的讀取,是不會產生咬死的狀況喔!很古老的資料了,但是每次要實作總會因為膽戰心驚又要去找一次資料,因此將其記錄在這裡嘍!
寫入跟讀取的情況又不太一樣了,因為對OS來說,寫入檔案在怎麼神奇,永遠同時間也是只能一個執行緒使用而已,因此如果場景搬到Web上,最好上個lock把執行緒序列化一下會比較安全。
private static System.Object _oLock = new System.Object(); public void WriteUpdate() { lock (_oLock) { using (System.IO.StreamWriter oSW = new System.IO.StreamWriter( new System.IO.FileStream ( path: cFilePathAndName, mode: System.IO.FileMode.OpenOrCreate, access: System.IO.FileAccess.Write, share: System.IO.FileShare.ReadWrite ), System.Text.Encoding.UTF8 ) ) { oSW.WriteLine(YourData); oSW.Flush(); } } }
對於寫入的程式碼,這邊針對mode做一下小小的補充,如果你要寫入的速度效能最大化,那麼應該設定成System.IO.FileMode.OpenOrCreate,在多執行緒的情景實際測試下來會比System.IO.FileMode.Create的效能快約3倍以上(1xxms變成3xms)。
然而,有一好沒兩好,如果你這個檔案是要給ASP.NET做快取(Cache)監控用的,那麼System.IO.FileMode.Create會是你的最佳選擇,因為Create會把檔案砍掉重新創造一個新檔案,這會造成SMB的檔案監控馬上觸發,因此依存在這個檔案上的快取會馬上消失。而OpenOrCreate會進行檔案的開啟與修改,這時SMB的檔案監控機制沒有辦法馬上反應,反而要等待10~15秒左右才會觸發(發現這個檔案被異動過),這對網站要求Cache要即時因為修正檔案而反應的效率上,因而大打折扣喔!