現在 diaries.json 已經存在裝置中(欸,照我們的設計,要先「新增過日記才行」),如果本機端有這個 JSON 檔案,就可以直接還原,這樣 UUID 就不會變,就可以確認日記是同一筆囉。(為什麼會變?請複習 Day11)
上一章介紹將資料轉換成 JSON Object ,接著一筆一筆存到 JSON Array(陣列),最後寫入本機的 JSON 檔案之中。今天要將流程「反過來」做,也就是讀取 JSON 檔案的內容,將一切倒回來。
寫入 json 檔案的最後一個步驟,就是將整坨 JSON 轉成 String 塞到檔案中。
diaryFile.writeText(jsonArray.toString())
把 JSON 檔案放回電腦後打開,也注意到的確是一堆字組成。現在,反過來做的做法,就是將這些 JSON String 重新塞回 JSONArray 之中。
現來新增一個 load() 方法:

最上面直接檢查檔案是否存在,如果不存在也不用做了,直接回一個空值。(空值?請複習 Day07) 這招在實務上很常用,如果某個條件不符合,就直接跳回,這招叫:early return。這招的好處是往下看 Code 時,可以確定 diaryfile 一定存在。
然後就跟前面說的一樣,將 JSON String 塞到 Json Array 裡頭。為何可以這樣做呢?還記得這次的 JSON String 本體,就是被一個超大的 JSON Array 包起來的嗎?
[ // 👈🏼 這代表 [] 一個 Array
{
"id": "abc",
"title": "夜裡的共享空間",
"note": "雨夜裡留下來整理想法",
"mood": "專注",
"createdAt": "2026-04-04T21:04:51",
"photoResId": 123
}
]
如果列表不是被 Array 包圍,這樣做就會出錯而 Crash(App 死當),要注意喔。
接著創立一個可以修改的 List(如果是 List 是不能調整內容的囉,要加資料需要 MutableList 才行)。
接下來就是開迴圈 啦,這裡的 for 的意思是 index (索引)從 0 開始,直到 jsonArray 的長度。白話的意思就是 jsonArray 裏面有多少,就做多少次。
接下來做的事情是從 JSON Array 裡頭分別取出每一個 JSON Object,用索引就可以取出。然後透過建構子 (Constructor) 來建立 DiaryEntry,再塞回去 entries。
最後回傳這個 entries 列表即可。
這一塊調整就很簡單了,只要將上方狀態的
var entries by mutableStateOf(sampleEntries())
sampleEntries() 調整從本機取得資料即可。不過要先定義好讀取用的方法:

一樣依程式碼來說故事,從 storage.load() 來讀取本機的資料,藉由前面的程式碼得知如果有任何問題,他會回傳空值(Null)。
故下面的判斷方式即是:如果是空值,就維持從 sampleEntries() 產生資料;否則就直接回傳 LocalDiaryStorage load 的資料就好囉。
然後上面那行改成:
var entries by mutableStateOf(loadInitialEntries())
這樣就大功告成囉!每次建立 entries 時,就會去跑 ViewModel 寫好的 loadInitialEntries() 方法囉。

DiaryEntry,這樣日記才能從檔案復活。load() 一開頭檢查檔案不存在就回空值,好處是往下看 Code 時可以確定 diaryFile 一定存在。jsonArray.toString() 變成一坨字,讀取時把這坨字塞回 JSONArray;能這樣做的前提是字串本體本來就是被 [] 包起來的 Array,格式不對就會出錯 Crash。List 不能調整內容,要一筆一筆加資料必須用 MutableList,所以還原時先建一個可修改的列表來裝成果。jsonArray 的長度,白話就是裡面有幾筆資料就做幾次,把每個 JSON Object 都輪過一遍。