Contents

如何在 Node.js 中讀寫 JSON 文件

可以在 Node.js 中讀取和寫入 JSON 檔案。您所需要做的就是使用 fs 模組,如我們易於遵循的指南中詳細介紹的那樣。

在 Node.js 中讀寫 JSON 文件

JavaScript 物件表示法 (JSON) 是一種非常流行的資料傳輸標準,尤其以其以簡潔的方式表示有組織的資訊的能力而聞名。這種格式的特點是文字性質,有助於人類使用者輕鬆理解,同時也允許機器處理系統無縫解析和生成。

利用 Node.js 中自動解析和產生 JSON 資料的功能,可以促進高效、輕鬆地儲存、傳輸和操作結構化資訊。透過使用 Node.js 檔案系統元件,全面了解讀取、編寫和修改 JSON 檔案。

Node.js 檔案系統模組

Node.js 檔案系統模組本身就整合在 Node.js 環境中,使用戶能夠透過各種功能(例如讀取檔案、建立新檔案和刪除檔案等)與其裝置的檔案系統進行通訊。

檔案系統模組提供的功能有兩種不同的形式:它們可以非同步或同步進行。非同步操作不會阻礙應用程式的進程,因為它們允許與其他任務並發處理。遵循這種模式的方法通常具有表示其非同步性質的名稱。例如,我們會發現方法名稱後面附加了諸如“Async”或“await”之類的名稱,例如“readFileAsync”或“writeFileAsync”。

同步方法會暫停程式的執行,直到檔案系統作業完成,而非同步方法則允許程式透過利用在操作結束時執行的回呼函數來同時處理其他任務。說明性範例包括 readFile 和 writeFile 函數。

為了保持事件循環的非阻塞特性並提高應用程式在處理文件時的整體效率和及時性,必須在與文件系統的所有互動中使用非同步技術。

在簡單性至關重要且操作不頻繁的特定情況下,例如對於基本腳本任務或一次性文件操作,非同步方法可能不是必需的,而同步技術可以證明是一種有效的解決方案。

使用 fs 模組讀取 JSON 文件

為了使用非同步 JavaScript 處理 JSON 文件,需要將非同步檔案系統模組匯入到主腳本檔案中。這可以透過在檔案開頭包含 import 語句來實現,如下所示:

 const fs = require("node:fs/promises");

如果使用早於版本 18 的 Node.js 版本,則必須以以下方式匯入 fs 模組:

 const fs = require("fs/promises");

如果希望導入完整的模組,包括同步和非同步元件,則有必要從導入語句中省略“/promises”。

利用 readFile 函數,我們可以透過提供目錄路徑和可選配置物件作為參數來仔細閱讀 JSON 檔案的內容。此配置對象可以是包含各種閱讀偏好的JavaScript對象,也可以是封裝預定編碼方案的字串。

物件選項包括:

指定的參數決定了閱讀特定文件過程中使用的字元集,標準配置為“utf8”,通常用於文字內容,而「二進位」適用於非文字資料檔案。

星號 (*) 符號後面跟著括號,括在大括號 ({}) 內,表示可選參數,預設值為“r”,代表在特定檔案系統中開啟檔案時的讀取模式。其他常見的檔案存取模式包括「w」表示只寫模式和「a」表示追加模式。

例如:

 fs.readFile("./users.json", { encoding: "utf-8", flag: "r" })
  .then((data) => {
    const users = JSON.parse(data);
    console.log(users);
  })
  .catch((error) => {
    console.error('Error reading the JSON file:', error);
  });

目前的應用程式旨在處理儲存在名為「users.json」的檔案中的信息,該檔案位於軟體執行點附近。為了提取該特定文件的內容,可以利用所採用的程式語言所提供的內建功能。具體來說,可以對檢索到的資料呼叫稱為「JSON.parse」的方法,以便將其轉換為 JavaScript 物件。透過這樣做,用戶可以獲得與其中包含的資訊進行互動和修改的能力,所有這些都在其程式碼庫的範圍內。

當處理較小的 JSON 檔案時,可以利用 require 函數同步解析此類檔案並將其內容轉換​​為 JavaScript 物件。但是,對於更大量的 JSON 檔案或在非同步上下文中工作時,建議改用「 fs.readFile 」方法。值得注意的是,「require」方法有可能將檔案的全部內容快取在記憶體中,如果 JSON 資料頻繁更改,這可能會導致困難。

使用 fs 模組來撰寫 JSON 文件

writeFile 函數允許建立和寫入 JSON 格式的數據,透過提供三個參數,即檔案路徑、要寫入的數據和可選的回調函數。

⭐文件路徑。

用於儲存在檔案中的資訊可以採用各種形式,例如字串、緩衝區、非同步可迭代物件或可迭代物件。

⭐可選的配置物件。

這種特定方法採用非同步操作來將資料寫入指定檔案。如果所述文件已經存在,則其當前內容將被所提供的資料替換,從而有效地取代可能已儲存在其中的任何先前資訊。相反,在文件尚不存在的情況下,該技術將建立該文件並隨後使用作為輸入傳遞的資料填充該文件,從而確保所有必要的資訊成功保存在指定的儲存位置內。

例如:

 const fakeUsers = [
  {
    id: 1,
    name: "John Doe",
    username: "johndoe123",
    address: {
      street: "123 Main St",
      city: "Anytown",
    },
  },
  {
    id: 2,
    name: "Jane Smith",
    username: "janesmith456",
    address: {
      street: "456 Elm St",
      city: "Another City",
    },
  }
];

fs.writeFile("./users.json", JSON.stringify(fakeUsers), {
  encoding: "utf-8",
  flag: "w",
}).catch((error) => {
  console.error('Error writing the JSON file:', error);
});

字串或緩衝區。如果希望在該檔案中保存一個對象,則需要事先使用 JSON.stringify 方法將其轉換為字串。

使用 fs 模組更新 JSON 文件

所提供的程式碼不提供修改文件的直接方法,因為寫入文件會擦除其先前的內容。

為了克服這個挑戰,一種方法是利用 readFile 函數檢索文件的現有內容。隨後,人們可以將更新的資料與檢索到的資訊連接起來,並將兩個資料集作為「writeFile」操作的輸入提供。

當然,以下是一個 Python 函數的範例,它體現了概述的邏輯:

 const updateFile = async (filePath, data) => {
  try {
    const fileContents = await fs.readFile(filePath, {
      encoding: "utf-8",
      flag: "r",
    });

    const fileData = JSON.parse(fileContents);

    const updatedFileData = [...fileData, ...data];

    await fs.writeFile(filePath, JSON.stringify(updatedFileData), {
      encoding: "utf-8",
      flag: "w",
    });

    return "File updated successfully";
  } catch (error) {
    console.error('Error updating the JSON file:', error);
  }
};

您可以像這樣呼叫該函數:

 updateFile("./users.json", [
  {
    id: 4,
    name: "Jane Doe",
    username: "janedoe123",
    address: {
      street: "123 Main St",
      city: "Anytown",
    },
  },
  {
    id: 5,
    name: "John Smith",
    username: "johnsmith456",
    address: {
      street: "456 Elm St",
      city: "Another City",
    },
  }
]).then((message) => {
  console.log(message);
});

此程式碼片段會將上述使用者的詳細資訊附加到名為「users.json」的現有 JSON 檔案中。

讀寫 JSON 檔案的安全注意事項

確保處理 JSON 檔案的 Node.js 應用程式的安全性至關重要,因為此類操作涉及安全保護的關鍵方面。為了確保符合預先定義的規範,驗證 JSON 資料的有效性至關重要。此外,限製檔案的存取權限和清理使用者輸入是應對程式碼注入攻擊等潛在威脅的有效措施。