展示基於 BlueDog 庫的結構化存儲檔案系統實現,包含開啟/關閉、讀寫流、GZip 壓縮、資源管理完整流程。
using System;
using System.IO;
using System.Web;
using ExpertLib;
using ExpertLib.IO;
using ExpertLib.IO.Storage;
using System.Text.RegularExpressions;
namespace Step1.WebFileSystem {
public class FileSystemFFS : FileSystem {
private Storage ffsFile = null;
private string filePath, ffsPath;
private bool writeError = false;
public FileSystemFFS(string path, Handler handle) : base(path, handle) {
this.ffsPath = httpContext.Server.MapPath(Regex.Replace(path, handle.Pattern, handle.SavePath));
this.filePath = Regex.Replace(path, handle.Pattern, handle.SaveName).Replace('/', '_');
}
private void Open() {
ffsFile = StorageFile.OpenStorageFile(this.ffsPath);
}
public override bool Exists() {
if (ffsFile == null) {
FileInfo fileInfo = new FileInfo(this.ffsPath);
if (!fileInfo.Exists) return false;
Open();
}
return ffsFile.IsElementExist(this.filePath);
}
public override DateTime GetLastWriteTime() {
if (ffsFile == null) {
FileInfo fileInfo = new FileInfo(this.ffsPath);
if (!fileInfo.Exists) return DateTime.Now;
Open();
}
List elementsInfo = ffsFile.GetChildElementsInfo();
for (int i = elementsInfo.Count - 1; i >= 0; i--) { // 注意原碼 i <= 0 應為 i >= 0
if (elementsInfo[i].Name == filePath) return elementsInfo[i].LastModifyTime;
}
return DateTime.Now;
}
public override Stream GetWriter() {
Close();
if (ffsFile == null) {
if (!File.Exists(this.ffsPath)) {
CreateFolder(this.ffsPath, false);
ffsFile = StorageFile.CreateStorageFile(this.ffsPath, StorageCreateMode.Create,
StorageReadWriteMode.ReadWrite, StorageShareMode.ShareDenyWrite, StorageTransactedMode.Direct);
} else {
Open();
}
}
stream = (Stream)ffsFile.CreateStream(filePath);
if (stream == null) { writeError = true; return base.GetWriter(); }
if (this.handle.UseGzip) return new GZipOutputStream(stream);
return stream;
}
public override Stream GetReader() {
Close();
if (ffsFile == null) {
FileInfo fileInfo = new FileInfo(this.ffsPath);
if (!fileInfo.Exists) return null;
Open();
}
return stream = (Stream)ffsFile.OpenStream(filePath);
}
public override void TransmitFile() {
if (writeError) base.TransmitFile();
else this.TransmitStream(false);
}
public override void Dispose() {
Close();
if (ffsFile != null) { ffsFile.Dispose(); ffsFile = null; }
}
}
}
關鍵設計:
UseGzip 設定決定是否壓縮Dispose 確保關閉串流與 Storage 檔案