選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
2 分鐘閱讀時間 (464 個字)

[C#] File.Create 鎖定檔案

unsplash-coding071
由於很久沒有寫Stream.IO 的相關程式,剛好今天有一個需求是Parser 文件,「判斷檔案是否存在,不存在就建立新的檔案,存在就寫檔」,結果碰到一個寫檔入門常見的錯誤,

類型 'System.IO.IOException' 的未處理例外狀況發生於 mscorlib.dll 其他資訊: 由於另一個處理序正在使用檔案 'C:\Users\Administrator\Desktop\xxxx.xml',所以無法存取該檔案。


直覺反應這是串流沒有被正常關閉,導致另一個串流想要IO的時候被Lock 住了。

程式範例:

//檔案路徑
string filePath = string.Format("{0}\\{1}.xml", Directory.GetCurrentDirectory(), DateTime.Now.ToString("HH-mm-ss"));
//判斷檔案是否存在,不存在就開一個新檔案
if (!File.Exists(filePath))
{
File.Create(filePath);
}
//開始寫檔
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.WriteLine("寫檔成功");
}

看起來很直覺,且還有使用好寫法「[C#] using statement(陳述式) 資源(IO)控管好寫法!」,

但為何會出現'System.IO.IOException',而且神奇的是“檔名”固定的條件下,程式重開後就不會有這個錯誤了!

依據這個線索,發現有問題的是File.Create(),官方文件有寫道 File.Create() 後會回傳 FileStream,也就是說,若你沒有接住這個FileStream, 在程式執行期間,這個資源是被Lock住的;換句話說,因為你沒接住這個FileStream,你也無法操控它並且釋放。

應改用以下寫法:

//檔案路徑
string filePath = string.Format("{0}\\{1}.xml", Directory.GetCurrentDirectory(), DateTime.Now.ToString("HH-mm-ss"));
//判斷檔案是否存在,不存在就開一個新檔案
if (!File.Exists(filePath))
{
using (FileStream fs = File.Create(filePath))
{
}
}
//開始寫檔
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.WriteLine("寫檔成功");
}

或是:

//檔案路徑
string filePath = string.Format("{0}\\{1}.xml", Directory.GetCurrentDirectory(), DateTime.Now.ToString("HH-mm-ss"));
//判斷檔案是否存在,不存在就開一個新檔案
if (!File.Exists(filePath))
{
using (FileStream fs = File.Create(filePath))
{
}
}
//開始寫檔
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.WriteLine("寫檔成功");
}

另外,大家應該可以發現,上述的程式碼都有使用 StreamWriter ,

其實很像從頭到尾,都不需要使用File.Create()來開新檔案,StreamWriter 本上就會判斷檔案是否存在,不存在就建立新的檔案,

所以程式法簡略成這樣即可:

//檔案路徑
string filePath = string.Format("{0}\\{1}.xml", Directory.GetCurrentDirectory(), DateTime.Now.ToString("HH-mm-ss"));
//開始寫檔
using (StreamWriter sw = new StreamWriter(filePath,true))
{
sw.WriteLine("寫檔成功");
}

所以還是套一句老話,用任何工具之前請先熟悉他。

本文也發表於Harry’s Tech World
[Asp .Net MVC] ViewMode vs DTO(Data Transfer Objec...
資安弱點與解決範例

相關文章

 

評論 1

Guest - VegFarmer 於 2023/02/13, 週一 00:52

應改用以下寫法:
XXXXXX
或是:
YYYYYY

不過文章裡XXXXXX與YYYYYY兩段程式碼好像一膜一樣?

應改用以下寫法: XXXXXX 或是: YYYYYY 不過文章裡XXXXXX與YYYYYY兩段程式碼好像一膜一樣?
已經注冊了? 這裡登入
Guest
2024/04/26, 週五

Captcha 圖像