C# 檔案管理的FilesManager物件要考慮哪些點?
先前有寫到C# Web API我會將其中一層做成Manager層,或者稱作Operations層(但我比較喜歡Manager這個詞)。以下大概解釋一下如果Web API要做到上傳檔案到檔案系統的FileManager,大概要考慮哪些點。
這邊只寫檔案的創建和刪除,不然整個物件全部寫上來大概要5000多字。
CreateFileToDisk
宣告我會寫成:
private bool CreateFileToDisk(byte[] FileBytes,string FileHashCode)
第一個當然就是要寫把bytes變成檔案的放到伺服器的FileSystem(也就是Disk)裡面的。
這裡我FileHashCode會用SHA256,把bytes算一個HashCode來當檔名,存到如C:\FileStorage\的目錄,記得要確保Web有這麼目錄的權限。
所以要寫一個公用的Function是SHA256多載針對string和byte[]的。
public string SHA256(byte[] input)
public string SHA256(string input)
AddFileToTopic
AddFile需要傳入byte[]、FileName,還有要綁定的表的PK這裡我以Topic作例子,就是TopicID,所以宣告應該是這樣:
public bool AddFileToTopic(byte[] FileBytes,string FileName,string TopicID)
然後要做的事情第一件事情是算SHA256 HashCode,接著呼叫File.Exists確認檔案是否已經在。
如果不在則呼叫CreateFileToDisk,bool都是確認是否有例外狀況。
然後沒有例外狀況的話,再確認一次File.Exists,就可以寫入資料庫說硬碟有這個檔案,且跟哪個Topic連結。
private bool LinkFileAndTopic(string FileHashCode,string TopicID)
實作資料表的Insert,如果已經有資料的例外處理。
做完以後就傳回true,AddFileToTopic就完成。
FileUsed
public/private int FileUsed(string FileHashCode)
用來取得Topic或者別的有連結FileHashCode的總數。
這個是SafeDeleteFile的前置。
SafeDeleteFile
SafeDeleteFile比較麻煩,一定要確認資料表中沒有用到同樣的FileHashCode才可以刪掉檔案,不然程式在抓檔案會出錯。
public bool SafeDeleteFile(string FileHashCode,bool Force=false)
如果Force不是true就是不是要強制刪除檔案(我暫時想不到有哪個狀態需要強制刪除導致程式出錯)。
就做FileUsed判斷,如果是0就代表檔案已經沒有用到,就可以用內建的File物件把檔案刪掉,但這邊要例外判斷,因為可能檔案使用中。
但這邊一定有人在想,至少會是1啊?讓它變0是別的Manager的事情,比如說TopicFilesManager的事情,也就是TopicManager.Delete會先呼叫TopicFileManager.Delete才呼叫FileManager.SafeDeleteFile。
寫成這麼多個有好處嗎?當然有,單元測試的時候很好測試,寫多一點例外狀況比如開啟檔案還要刪除檔案這種極限例外狀況,如果都處理好程式Bugs會少很多。
ClearUnusedFiles
public void ClearUnusedFile()
這個一定要有,不然如果有例外狀況如檔案開啟中,SafeDeleteFile失敗,但資料庫的資料已經刪除掉了。
這個函數會去確認資料庫有哪些FileHashCode和資料夾有哪些,一一作比對,只要資料庫沒有的就把資料夾的刪掉,算是系統維護作業之一。
GetFilesAreMissing
public string[] GetFilesAreMissing()
這也是系統維護作業,看看有哪些檔案已經丟掉,但資料庫還有的。傳回這些檔案的Hash Code陣列,再看要怎樣處理這些資料。
思考的點
其實如果是TopicManager.Delete-(呼叫)->TopicFilesManager.Delete-(呼叫)>FileManager.SafeDeleteFile,結果SafeDeleteFile傳回false。
那可以考慮這筆Topic資料就不刪除,只要用一連串的if敘述判斷就好了,這種做法檔案系統會比較安全,但使用者會比較常抱怨,「為什麼我要刪除topic會一直顯示檔案使用中?」,可能會一直聽到這個疑問。
這就是要考量的點了,至於ClearUnusedFiles可以用Web API做,也可以寫一個Console程式用Windows排程去做,或者寫個Worker來做。
有很多地方都可以細節優化或者做得更好,我這邊也只是丟出我在2023年11月28日寫完的時候思考到的點,也許有些可以優化得更好,這就交給觀看文章的您思考了。