在 Delphi 開發中,檔案處理是不可或缺的一部分。本文將示範如何使用 TStreamWriter 和 TStreamReader 簡化文字檔的讀寫操作。同時,我們也將探討如何使用 JSON 格式儲存結構化資料,並示範使用 TJSONObject 和 TJsonTextWriter 兩種方式生成 JSON 資料,最後將其寫入檔案。透過這些技巧,可以更有效率地處理檔案,並提升資料儲存的結構性。程式碼範例中詳細展示瞭如何讀取我的最愛清單,並將其轉換為文字和 JSON 格式儲存,方便後續讀取和應用。這兩種方法各有優劣,TJSONObject 適合建立複雜的 JSON 結構,而 TJsonTextWriter 則更注重效能和程式碼可讀性。
使用 TStreamWriter 和 TStreamReader 處理文字檔
在程式開發中,檔案操作是常見的需求。Delphi 提供多種方式來建立和操作檔案,例如使用內建函式、專門的類別(如 TMemo 或 TIniFile),或是 System.IOUtils 單元中的 TFile 類別。不過,最簡便的方法是使用 System.Classes 單元中的 TStreamWriter 和 TStreamReader 類別,它們提供了一個優雅的程式設計模型來進行檔案操作。
建立範例應用程式
首先,我們在主表單上新增一個按鈕,用於顯示另一個表單,在那裡我們將嘗試不同的文字檔處理方法。將新表單儲存在 uFormFavTextFiles 單元中,並將表單重新命名為 FormFavTextFiles。
導航程式碼實作
在主表單中,我們新增一個按鈕點選事件,用於顯示 FormFavTextFiles:
uses
uFormFavTextFiles;
procedure TFormFavMain.BtnTextFilesClick(Sender: TObject);
begin
FormFavTextFiles.Show;
end;
同樣地,在 FormFavTextFiles 中,我們新增一個按鈕點選事件,用於傳回主表單。
使用 TStreamWriter 和 TStreamReader
在 FormFavTextFiles 上,我們新增兩個按鈕和一個 TMemo 元件,分別用於寫入和讀取我的最愛清單到文字檔,並顯示結果。
取得檔案名稱的函式
首先,我們定義一個 GetFilename 函式,用於集中管理檔案名稱的存取:
uses
uFormFavMain, uFavorite, System.IOUtils;
function TFormFavTextFiles.GetFilename: string;
begin
Result := TPath.Combine(TPath.GetDocumentsPath, 'favs.txt');
end;
這個函式使用 TPath.Combine 方法來組合檔案路徑和檔名,以確保跨平台相容性。
寫入我的最愛到文字檔
當第一個按鈕被點選時,我們將我的最愛清單寫入到文字檔:
procedure TFormFavTextFiles.BtnWriteClick(Sender: TObject);
var
SW: TStreamWriter;
Fav: TFavorite;
Favs: TFavorites;
begin
Favs := FormFavMain.Favs;
SW := TStreamWriter.Create(GetFilename, False, TEncoding.UTF8);
try
for Fav in Favs do
begin
SW.WriteLine(Fav.URL);
SW.WriteLine(Fav.Caption);
end;
finally
SW.Free;
end;
end;
#### 內容解密:
- 此段程式碼首先取得主表單中的我的最愛清單,並建立一個
TStreamWriter物件用於寫入檔案。 - 使用迴圈遍歷我的最愛清單,將每個專案的 URL 和 Caption 寫入檔案。
- 使用
TEncoding.UTF8編碼確保檔案內容的正確性。 - 最後釋放
TStreamWriter物件以避免記憶體洩漏。
讀取文字檔內容
當第二個按鈕被點選時,我們讀取文字檔的內容並顯示在 Memo 中:
procedure TFormFavTextFiles.BtnReadClick(Sender: TObject);
var
SR: TStreamReader;
begin
SR := TStreamReader.Create(GetFilename, TEncoding.UTF8);
try
while not SR.EndOfStream do
MemoLog.Lines.Add(SR.ReadLine);
finally
SR.Free;
end;
end;
#### 內容解密:
- 此段程式碼建立一個
TStreamReader物件用於讀取檔案。 - 使用迴圈讀取檔案的每一行,並將其新增到 Memo 的 Lines 中。
- 使用
TEncoding.UTF8編碼確保檔案內容的正確性。 - 最後釋放
TStreamReader物件以避免記憶體洩漏。
JSON 資料處理簡介
雖然使用 TStreamWriter 和 TStreamReader 可以實作基本的檔案操作,但資料缺乏結構化。對於我的最愛清單這種結構化資料,使用 JSON 格式儲存會更合適。Delphi 提供兩種方式來處理 JSON 資料:建立記憶體中的 JSON 物件樹,或是使用串流方式順序存取 JSON 資料。接下來,我們將探討如何使用 JSON 來儲存和讀取我的最愛清單。
圖表翻譯:
此圖表呈現了使用 TStreamWriter 和 TStreamReader 處理文字檔的流程。首先,建立 TStreamWriter 將我的最愛清單寫入檔案;然後,建立 TStreamReader 讀取檔案內容並顯示在 Memo 中。整個過程確保了資料的正確寫入和讀取。
使用JSON進行資料交換
JSON是一種非常流行的資料交換格式,用於分享資訊和各類別資料集。假設你剛剛在本機下載了一份JSON資料,接下來該怎麼做呢?
JSON範例
以下是一個表示收藏資訊的JSON範例:
{
"Favorites": [
{
"URL": "www.embarcadero.com/products/delphi",
"Caption": "Delphi Home Page"
},
{
"URL": "docwiki.embarcadero.com/RADStudio/en",
"Caption": "RAD Studio online documentation"
}
]
}
與最初建立的純文字檔不同,JSON中的收藏資料結構更為嚴謹。這裡有一個物件,只有一個名為Favorites的屬性,其值是一個包含兩個物件的陣列。陣列中的每個物件都有兩個字串屬性:URL和Caption。
對於程式設計師來說,一個典型的目標是將JSON資料轉換成可以在程式碼中操作的程式語言結構,或從程式輸出JSON文字。
建立JSON
首先,我們來看看生成JSON的不同方法。我們將把這些資訊儲存到檔案中,稍後再將這些資訊讀回本地的收藏清單。
取得檔案名稱
我們首先實作一個GetFilename函式,用於寫入和讀取favs.json檔案:
function TFormFavJSON.GetFilename: string;
begin
Result := TPath.Combine(TPath.GetDocumentsPath, 'favs.json');
end;
將JSON文字寫入檔案
我們還需要一個簡單的函式,將包含JSON文字的字串寫入檔案。使用TStreamWriter類別,可以輕鬆實作這一點:
procedure TFormFavJSON.WriteJsonTextToFile(txt: string);
var
sw: TStreamWriter;
begin
sw := TStreamWriter.Create(GetFilename, False, TEncoding.UTF8);
try
sw.WriteLine(txt);
finally
sw.Free;
end;
end;
使用DOM生成JSON
第一種生成JSON的方法是建立一個記憶體中的JSON資料圖形,然後一次性將其轉換為字串。為此,我們將定義FavListToJsonTextWithDOM方法,該方法將從demo app主表單的全域TFavorites清單中生成JSON文字:
function TFormFavJSON.FavListToJsonTextWithDOM: string;
var
Fav: TFavorite;
Favs: TFavorites;
ObjFavs, ObjF: TJSONObject;
ArrFavs: TJSONArray;
begin
Favs := FormFavMain.Favs;
ObjFavs := TJSONObject.Create;
try
ArrFavs := TJSONArray.Create;
for Fav in Favs do
begin
ObjF := TJSONObject.Create;
ObjF.AddPair('URL', TJSONString.Create(Fav.URL));
ObjF.AddPair('Caption', TJSONString.Create(Fav.Caption));
ArrFavs.Add(ObjF);
end;
ObjFavs.AddPair('Favorites', ArrFavs);
Result := ObjFavs.ToString;
finally
ObjFavs.Free;
end;
end;
程式碼解密:
- 初始化變數:首先,我們從主表單取得
Favs,並建立一個名為ObjFavs的TJSONObject例項。 - 建立JSON陣列:我們建立一個名為
ArrFavs的TJSONArray,用於儲存多個TFavorite物件。 - 迴圈處理:遍歷
Favs中的每個TFavorite物件,建立對應的TJSONObject(ObjF),並新增URL和Caption屬性。 - 加入陣列:將每個
ObjF加入到ArrFavs中。 - 組合JSON物件:將
ArrFavs加入到ObjFavs中,並以Favorites為屬性名稱。 - 輸出JSON字串:呼叫
ObjFavs.ToString將整個JSON物件轉換為字串。 - 資源釋放:最後,釋放
ObjFavs,它會自動釋放其擁有的所有子物件。
在表單上新增一個按鈕,將其Caption屬性設為「Write with JSON DOM」,並在其OnClick事件中輸入以下程式碼:
procedure TFormFavJSON.btnWriteDOMClick(Sender: TObject);
var
S: string;
begin
S := FavListToJsonTextWithDOM;
WriteJsonTextToFile(S);
end;
使用TJsonTextWriter生成JSON
第二種生成JSON的方法涉及使用 TJsonTextWriter類別。讓我們在表單類別中定義 FavListToJsonTextWithWriter方法,該方法傳回一個字串:
function TFormFavJSON.FavListToJsonTextWithWriter: string;
var
Fav: TFavorite;
Favs: TFavorites;
StringWriter: TStringWriter;
Writer: TJsonTextWriter;
begin
Favs := FormFavMain.Favs;
StringWriter := TStringWriter.Create();
Writer := TJsonTextWriter.Create(StringWriter);
try
Writer.Formatting := TJsonFormatting.Indented;
Writer.WriteStartObject;
Writer.WritePropertyName('Favorites');
Writer.WriteStartArray;
for Fav in Favs do
begin
Writer.WriteStartObject;
Writer.WritePropertyName('URL');
Writer.WriteValue(Fav.URL);
Writer.WritePropertyName('Caption');
Writer.WriteValue(Fav.Caption);
Writer.WriteEndObject;
end;
Writer.WriteEndArray;
Writer.WriteEndObject;
Result := StringWriter.ToString;
finally
Writer.Free;
StringWriter.Free;
end;
end;
程式碼解密:
- 初始化寫入器:首先,建立一個
TStringWriter和一個TJsonTextWriter,用於寫入JSON內容。 - 設定格式:將
Writer.Formatting設定為TJsonFormatting.Indented,以產生縮排格式的JSON。 - 寫入JSON結構:使用
WriteStartObject,WritePropertyName,WriteStartArray, 和WriteValue等方法逐步寫入JSON結構和資料。 - 迴圈處理:遍歷每個
TFavorite物件,寫入其URL和Caption。 - 結束寫入:關閉所有開啟的JSON結構。
- 取得結果:將
StringWriter中的內容轉換為字串並傳回。 - 資源釋放:釋放
Writer和StringWriter。
使用 TJsonTextWriter 的方法比DOM方法更冗長,但它不會分配臨時物件,使程式碼更具可讀性,並且可以輕易預覽最終生成的JSON內容。
圖表翻譯:
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Delphi 使用 TStreamWriter TStreamReader 處理文字與 JSON 檔
package "物件導向程式設計" {
package "核心概念" {
component [類別 Class] as class
component [物件 Object] as object
component [屬性 Attribute] as attr
component [方法 Method] as method
}
package "三大特性" {
component [封裝
Encapsulation] as encap
component [繼承
Inheritance] as inherit
component [多型
Polymorphism] as poly
}
package "設計原則" {
component [SOLID] as solid
component [DRY] as dry
component [KISS] as kiss
}
}
class --> object : 實例化
object --> attr : 資料
object --> method : 行為
class --> encap : 隱藏內部
class --> inherit : 擴展功能
inherit --> poly : 覆寫方法
solid --> dry : 設計模式
note right of solid
S: 單一職責
O: 開放封閉
L: 里氏替換
I: 介面隔離
D: 依賴反轉
end note
@enduml此圖示呈現了生成JSON的主要步驟,從初始化變數到輸出最終的JSON字串。