專案需求:掃描指定目錄下所有子資料夾,每個資料夾對應一組設定 (存於 INI 檔),將資料夾名稱與設定值繫結至 GridView 顯示。本文示範 Directory.GetDirectories 遞迴遍歷、INI 檔讀取封裝、DataTable 動態建構與繫結完整流程。
public partial class FolderConfigList : System.Web.UI.Page
{
private readonly Helper _helper = new Helper(); // 假設封裝好遞迴取資料夾方法
private readonly INI.INIFile _iniFile; // 假設封裝好 INI 讀寫類別
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) BindGrid();
}
private void BindGrid()
{
// 1. 取得 APPDIR 下所有子資料夾完整路徑 (以逗號分隔字串回傳)
string folderPathsCsv = _helper.GetAllFolder(Server.MapPath("~/APPDIR"));
string[] folderPaths = folderPathsCsv.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
// 2. 建構 DataTable
var dt = new DataTable();
dt.Columns.Add("LKNAME", typeof(string)); // 資料夾名稱
dt.Columns.Add("QDJJM", typeof(string)); // INI 設定值1
dt.Columns.Add("QDIP", typeof(string)); // INI 設定值2
foreach (string fullPath in folderPaths)
{
string folderName = Path.GetFileName(fullPath); // 取得資料夾名稱
var row = dt.NewRow();
row["LKNAME"] = folderName;
// 3. 讀取 INI 設定 (Section="dzjclkzp", Key=資料夾名稱, Value="值1,值2")
string iniValue = _iniFile.IniReadValue("dzjclkzp", folderName);
if (!string.IsNullOrEmpty(iniValue))
{
string[] parts = iniValue.Split(',');
if (parts.Length >= 2)
{
row["QDJJM"] = parts[0];
row["QDIP"] = parts[1];
}
}
dt.Rows.Add(row);
}
// 4. 繫結 GridView
gvwGKWH.DataSource = dt;
gvwGKWH.DataBind();
}
}
public class Helper
{
public string GetAllFolder(string rootPath)
{
var sb = new StringBuilder();
GetFoldersRecursive(rootPath, sb);
return sb.ToString();
}
private void GetFoldersRecursive(string path, StringBuilder sb)
{
try
{
foreach (string dir in Directory.GetDirectories(path))
{
sb.Append(dir).Append(',');
GetFoldersRecursive(dir, sb); // 遞迴處理子資料夾
}
}
catch (UnauthorizedAccessException) { /* 忽略無權限資料夾 */ }
}
}
public class INIFile
{
private readonly string _path;
[DllImport("kernel32", CharSet = CharSet.Unicode)]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
[DllImport("kernel32", CharSet = CharSet.Unicode)]
private static extern int WritePrivateProfileString(string section, string key, string value, string filePath);
public INIFile(string path) { _path = path; }
public string IniReadValue(string section, string key)
{
var sb = new StringBuilder(255);
GetPrivateProfileString(section, key, "", sb, 255, _path);
return sb.ToString();
}
public void IniWriteValue(string section, string key, string value)
{
WritePrivateProfileString(section, key, value, _path);
}
}
<asp:GridView ID="gvwGKWH" runat="server" AutoGenerateColumns="False" CssClass="table table-striped">
<Columns>
<asp:BoundField DataField="LKNAME" HeaderText="資料夾名稱" />
<asp:BoundField DataField="QDJJM" HeaderText="設定值1" />
<asp:BoundField DataField="QDIP" HeaderText="設定值2" />
<asp:TemplateField HeaderText="操作">
<ItemTemplate>
<asp:LinkButton runat="server" CommandName="Edit" CommandArgument='<%# Eval("LKNAME") %>'>編輯</asp:LinkButton>
</ItemTemplate>
</TemplateField>
</Columns>
</asp:GridView>
HttpRuntime.Cache 快取 DataTable,依賴 CacheDependency 監聽目錄變更 (需 .NET 4.0+ HostingEnvironment.MapPath 配合 FileSystemWatcher 或定時刷新)。PageAsyncTask 或前端 AJAX 分批載入。Server.MapPath 確保路徑在應用程式根目錄下,防止目錄遍歷攻擊。ReaderWriterLockSlim,或資料庫儲存設定。// .NET 4.0+ 建議用 EnumerateDirectories (延遲執行、記憶體友善) var folders = Directory.EnumerateDirectories(rootPath, "*", SearchOption.AllDirectories); // 設定檔改為 JSON (config.json) var config = JsonConvert.DeserializeObject>(File.ReadAllText(configPath)); var dt = new DataTable(); dt.Columns.Add("Name"); dt.Columns.Add("Value1"); dt.Columns.Add("Value2"); foreach (var folder in folders) { string name = Path.GetFileName(folder); if (config.TryGetValue(name, out var cfg)) dt.Rows.Add(name, cfg.Value1, cfg.Value2); }
本文示範傳統 Directory.GetDirectories 遞迴 + INI (P/Invoke) + DataTable 繫結 GridView 的完整流程。理解遞迴遍歷、非受控 API 封裝、動態建構資料表是 ASP.NET WebForms 處理檔案系統資料的核心技能。新專案建議採用 EnumerateDirectories、JSON 設定檔、非同步載入與快取策略提升效能與維護性。