C# 入門指南
單元 26 - 存檔與載入
存檔最簡單是將字串 (string) 儲存成文字檔案,因為字串最常用,所以 .NET 中有直接儲存字串為文字檔案的方式,這時候要加入以下的 using
下面看到存檔按鈕實作的 SaveButton_Click() 方法 (method)
以下為 SaveButton_Click() 的完整程式碼
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
string path = "code.text";
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
if (EncryptObject != null)
{
StreamWriter sw = new StreamWriter(fs, Encoding.Default);
sw.WriteLine(EncryptObject.Code);
sw.Close();
DisplayBlock.Text = "存檔完成!";
}
else
{
DisplayBlock.Text = "沒有編碼物件!";
}
}
}
完整程式請參考「範例程式篇」的「 MainWindow.xaml.cs 」。
首先建立 path 變數, path 是存檔的檔案路徑,這裡只有放檔案名稱,因此 code.text 會在專案 (project) 的 📁bin 資料夾中。
string path = "code.text";
然後檢查 EncryptObject 是否為 null ,因為如果 EncryptObject 是 null 就沒有 Code 屬性 (property) 可以儲存,注意到 using 這一行
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
這裡的 using 是建立 FileStream 型態的變數 fs ,也就是檔案物件,基本上會建立新的 code.text 。
此處 using 的作用與程式開頭引入程式庫 (library) 不同,這裡是讓 fs 的效力範圍只存在於底下大括弧的的空間,同時大括弧結束後自動釋放 fs 所佔據的記憶體空間。
下面當 EncryptObject 不是 null 就會啟動存檔程序
StreamWriter sw = new StreamWriter(fs, Encoding.Default);
sw.WriteLine(EncryptObject.Code);
sw.Close();
DisplayBlock.Text = "存檔完成!";
StreamWriter 型態的變數 sw 用來將文字內容寫入檔案,上面第 2 行用 WriteLine() 將 Code 屬性,也就是密碼表寫入檔案中,第 3 行呼叫 Close() 方法關閉 StreamWriter 的物件 sw ,工作完成後就在 DisplayBlock 顯示「存檔完成!」
繼續看到 LoadButton_Click() 方法
以下為 LoadButton_Click() 的完整程式碼
private void LoadButton_Click(object sender, RoutedEventArgs e)
{
string path = "code.text";
if (File.Exists(path))
{
StreamReader sr = new StreamReader(path);
EncryptObject = new Encrypt(sr.ReadLine());
sr.Close();
DisplayBlock.Text = "載入成功!";
}
else
{
DisplayBlock.Text = "載入失敗!";
}
}
同樣建立檔案路徑變數 path
string path = "code.text";
然後利用 File 類別的 Exists() 方法,判斷檔案是否存在
if (File.Exists(path))
由於 Exists() 是 static 方法,因此可以由類別名稱呼叫。
檔案存在才會進行載入工作
StreamReader sr = new StreamReader(path);
EncryptObject = new Encrypt(sr.ReadLine());
sr.Close();
DisplayBlock.Text = "載入成功!";
這裡換成用 StreamReader 型態的變數 sr ,並利用 ReadLine() 方法,讀取檔案的第一行,第一行也就是儲存密碼表的位置,然後把這一行的內容設定給新 Encrypt 型態的 EncryptObject 屬性。
重構版的 Encrypt 類別設計了可由參數建立密碼表 Code 屬性的建構子 (constructor) ,請參考單元 20 - 程式結構與重構。
繼續按上方的開始按鈕進行測試,先按新建按鈕建立密碼表物件
然後按存檔按鈕
切換到專案的 📁bin 中的 📁Debug 資料夾,可以看到多了 code.txt
編譯好的 WpfAppDemo.exe 就是放在 📁bin 中的 📁Debug 資料夾。
打開 code.txt ,可以看到裡頭第一行就是儲存密碼表
回到「編密碼小工具」視窗,進行編碼測試
換成其他的密碼表編碼
重新載入
重新用已儲存的密碼表編碼
存檔與載入,下一個單元繼續實作其他兩個拷貝與清除按鈕。
相關教學影片
中英文術語對照 | |
---|---|
建構子 | constructor |
程式庫 | library |
方法 | method |
專案 | project |
屬性 | property |
字串 | string |
參考資料 | |
---|---|
1. Visual Studio | Microsoft Docs - 使用 Visual Studio 進行 C# 開發 | |
2. Visual Studio | Microsoft Docs - 教學課程:使用 C# 建立一個簡單的應用程式 |
重點整理 |
---|
1. 存檔按鈕是直接把密碼表儲存到純文字檔案中,載入按鈕就直接用密碼表設定 Encrypt 物件。 |
2. 關鍵字 using 可以設定變數的效力範圍只存在於特定的程式區塊。 |
問題與討論 |
---|
1. 如果沒有 Encrypt 物件就進行存檔會怎麼樣呢? |
2. 為什麼載入前要先檢查檔案存不存在? |
練習 |
---|
1. 承接上一個單元的 HelloDemo 專案,將 ClickMe 的 Content 屬性設定為「已按」。 |
2. 承接上一個單元的 GuessGameDemo 專案,加入以下程式碼
|
3. 承上題,在 GameWindow 類別中加入 Guess 型態的 Game 屬性。 |
4. 承上題,快速點擊新遊戲按鈕兩次,建立 NewGame_Click() 方法,然後在 NewGame_Click() 中加入以下程式碼
|
5. 承上題,若按執行鍵會發生 Program.cs 的錯誤,此時回到 Program.cs 加入以下程式碼
|
6. 承上題,快速點擊重選按鈕兩次,建立 Reset_Click() 方法,然後在 Reset_Click() 中加入以下程式碼
|