Node.jsのfsモジュールを使用してファイルを操作する方法

提供:Dev Guides
移動先:案内検索

著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

ファイルの操作は、開発以外の目的と同様に、開発目的でも一般的です。 日常のコンピュータの使用では、ダウンロードしたファイルの保存や別のアプリケーションで使用するデータへのアクセスなどのタスクを実行するために、ユーザーはさまざまなディレクトリのファイルに対してデータの読み取りと書き込みを行う可能性があります。 同様に、バックエンドプログラムまたはコマンドラインインターフェイス(CLI)ツールは、ダウンロードしたデータを保存するためにファイルに書き込む必要がある場合や、データ集約型のアプリケーションをJSONにエクスポートする必要がある場合があります。 ]、 CSV 、またはExcel形式。 これらのプログラムは、それらが実行されているオペレーティングシステムのファイルシステムと通信する必要があります。

Node.js を使用すると、組み込みのfsモジュールを使用してファイルをプログラムで操作できます。 名前は「ファイルシステム」の略で、モジュールには、ローカルマシン上のファイルの読み取り、書き込み、および削除に必要なすべての機能が含まれています。 Node.jsのこのユニークな側面により、JavaScriptはバックエンドおよびCLIツールのプログラミングに役立つ言語になっています。

この記事では、fsモジュールを使用して、コマンドラインで作成したファイルの読み取り、新しいファイルの作成と書き込み、作成したファイルの削除、最初のファイルの別のフォルダーへの移動を行います。 fsモジュールは、同期、非同期、またはストリームを介したファイルとの対話をサポートします。 このチュートリアルでは、Node.js開発者が最も一般的に使用する方法である非同期のPromiseベースのAPIの使用方法に焦点を当てます。

前提条件

  • fsモジュールにアクセスしてチュートリアルに従うには、コンピューターにNode.jsがインストールされている必要があります。 このチュートリアルでは、Node.jsバージョン10.22.0を使用します。 Node.jsをmacOSまたはUbuntu18.04にインストールするには、Node.jsをインストールしてmacOSにローカル開発環境を作成する方法またはPPAを使用したインストールセクションの手順に従います。 X199X] Ubuntu18.04にNode.jsをインストールする方法。
  • この記事では、JavaScript Promisesを使用して、特にasync/await構文でファイルを操作します。 Promises、async/await構文、または非同期プログラミングに慣れていない場合は、Node.jsで非同期コードを作成する方法に関するガイドを確認してください。

ステップ1—readFile()でファイルを読み取る

このステップでは、Node.jsのファイルを読み取るプログラムを作成します。 これを行うには、ファイルを操作するための標準のNode.jsモジュールであるfsモジュールをインポートしてから、モジュールのreadFile()関数を使用する必要があります。 プログラムはファイルを読み取り、その内容を変数に格納してから、その内容をコンソールに記録します。

最初のステップは、このアクティビティと後のセクションのコーディング環境をセットアップすることです。

コードを保存するフォルダーを作成します。 ターミナルで、node-filesというフォルダーを作成します。

mkdir node-files

cdコマンドを使用して、作業ディレクトリを新しく作成したフォルダに変更します。

cd node-files

このフォルダに、2つのファイルを作成します。 最初のファイルは、プログラムが後で読み取るコンテンツを含む新しいファイルになります。 2番目のファイルは、ファイルを読み取るNode.jsモジュールになります。

次のコマンドを使用して、ファイルgreetings.txtを作成します。

echo "hello, hola, bonjour, hallo" > greetings.txt

echoコマンドは、そのstring引数を端末に出力します。 >を使用してリダイレクトechoの出力を新しいファイルgreetings.txtに転送します。

次に、選択したテキストエディタでreadFile.jsを作成して開きます。 このチュートリアルでは、ターミナルテキストエディタであるnanoを使用します。 このファイルは、次のようにnanoで開くことができます。

nano readFile.js

このファイルのコードは、3つのセクションに分けることができます。 まず、プログラムがファイルを操作できるようにするNode.jsモジュールをインポートする必要があります。 テキストエディタで、次のコードを入力します。

node-files / readFile.js

const fs = require('fs').promises;

前述のように、fsモジュールを使用してファイルシステムと対話します。 ただし、モジュールの.promises部分をインポートしていることに注意してください。

fsモジュールが最初に作成されたとき、Node.jsで非同期コードを記述する主な方法は、コールバックを使用することでした。 約束の人気が高まるにつれ、Node.jsチームは、箱から出してすぐにfsモジュールで約束をサポートするように努めました。 Node.jsバージョン10では、promiseを使用するfsモジュールにpromisesオブジェクトを作成しましたが、メインのfsモジュールは引き続きコールバックを使用する関数を公開しています。 このプログラムでは、モジュールのPromiseバージョンをインポートしています。

モジュールがインポートされたら、非同期関数を作成してファイルを読み取ることができます。 非同期関数は、asyncキーワードで始まります。 非同期関数を使用すると、.then()メソッドでpromiseをチェーンする代わりに、awaitキーワードを使用してpromiseを解決できます。

filePathという文字列という1つの引数を受け入れる新しい関数readFile()を作成します。 readFile()関数は、fsモジュールを使用して、async/await構文を使用してファイルを変数にロードします。

次の強調表示されたコードを入力します。

node-files / readFile.js

const fs = require('fs').promises;

async function readFile(filePath) {
  try {
    const data = await fs.readFile(filePath);
    console.log(data.toString());
  } catch (error) {
    console.error(`Got an error trying to read the file: ${error.message}`);
  }
}

asyncキーワードを使用して関数を定義し、後で付随するawaitキーワードを使用できるようにします。 非同期ファイル読み取り操作のエラーをキャプチャするには、fs.readFile()への呼び出しをtry...catchブロックで囲みます。 tryセクション内で、fs.readFile()関数を使用してファイルをdata変数にロードします。 その関数に必要な唯一の引数は、文字列として指定されたファイルパスです。

fs.readFile()は、デフォルトでbufferオブジェクトを返します。 bufferオブジェクトは、あらゆる種類のファイルタイプを保存できます。 ファイルの内容をログに記録するときは、バッファオブジェクトのtoString()メソッドを使用して、これらのバイトをテキストに変換します。

エラーが検出された場合、通常はファイルが見つからないか、プログラムにファイルを読み取る権限がない場合は、受信したエラーをコンソールに記録します。

最後に、greetings.txtファイルで、次の強調表示された行を使用して関数を呼び出します。

node-files / readFile.js

const fs = require('fs').promises;

async function readFile(filePath) {
  try {
    const data = await fs.readFile(filePath);
    console.log(data.toString());
  } catch (error) {
    console.error(`Got an error trying to read the file: ${error.message}`);
  }
}

readFile('greetings.txt');

必ず内容を保存してください。 nanoでは、CTRL+Xを押して保存して終了できます。

これで、プログラムは前に作成したgreetings.txtファイルを読み取り、その内容を端末に記録します。 nodeを使用してモジュールを実行し、これを確認します。

node readFile.js

次の出力が表示されます。

Outputhello, hola, bonjour, hallo

これで、async/await構文を使用して、fsモジュールのreadFile()関数でファイルを読み取ることができました。

注:以前のバージョンのNode.jsでは、fsモジュールを使用すると次の警告が表示されます。

(node:13085) ExperimentalWarning: The fs.promises API is experimental

fsモジュールのpromisesオブジェクトはNode.jsバージョン10で導入されたため、以前のバージョンの中にはまだモジュールを実験的なものと呼んでいるものがあります。 この警告は、バージョン12.6でAPIが安定したときに削除されました。


fsモジュールを使用してファイルを読み取ったので、次にファイルを作成してテキストを書き込みます。

ステップ2—writeFile()を使用してファイルを書き込む

このステップでは、fsモジュールのwriteFile()機能を使用してファイルを書き込みます。 食料品の請求書を追跡するCSVファイルをNode.jsに作成します。 初めてファイルを作成するときに、ファイルを作成してヘッダーを追加します。 2回目は、ファイルにデータを追加します。

テキストエディタで新しいファイルを開きます。

nano writeFile.js

fsモジュールをインポートしてコードを開始します。

node-files / writeFile.js

const fs = require('fs').promises;

2つの関数を作成するときは、引き続きasync/await構文を使用します。 最初の機能は、CSVファイルを作成することです。 2番目の機能は、CSVファイルにデータを追加することです。

テキストエディタで、次の強調表示されたコードを入力します。

node-files / writeFile.js

const fs = require('fs').promises;

async function openFile() {
  try {
    const csvHeaders = 'name,quantity,price'
    await fs.writeFile('groceries.csv', csvHeaders);
  } catch (error) {
    console.error(`Got an error trying to write to a file: ${error.message}`);
  }
}

この非同期関数は、最初に、CSVファイルの列見出しを含むcsvHeaders変数を作成します。 次に、fsモジュールのwriteFile()機能を使用してファイルを作成し、そこにデータを書き込みます。 最初の引数はファイルパスです。 ファイル名だけを指定したので、Node.jsは、コードを実行しているのと同じディレクトリにファイルを作成します。 2番目の引数は、書き込んでいるデータです。この場合は、csvHeaders変数です。

次に、食料品リストにアイテムを追加するための新しい関数を作成します。 テキストエディタに次の強調表示された関数を追加します。

node-files / writeFile.js

const fs = require('fs').promises;

async function openFile() {
  try {
    const csvHeaders = 'name,quantity,price'
    await fs.writeFile('groceries.csv', csvHeaders);
  } catch (error) {
    console.error(`Got an error trying to write to a file: ${error.message}`);
  }
}

async function addGroceryItem(name, quantity, price) {
  try {
    const csvLine = `\n${name},${quantity},${price}`
    await fs.writeFile('groceries.csv', csvLine, { flag: 'a' });
  } catch (error) {
    console.error(`Got an error trying to write to a file: ${error.message}`);
  }
}

非同期addGroceryItem()関数は、食料品の名前、購入する金額、およびユニットあたりの価格の3つの引数を受け入れます。 これらの引数は、 templateリテラル構文とともに使用され、ファイルに書き込んでいるデータであるcsvLine変数を形成します。

次に、openFile()関数で行ったように、writeFile()メソッドを使用します。 ただし、今回は3番目の引数があります:JavaScriptオブジェクト。 このオブジェクトには、値aflagキーがあります。 フラグは、Node.jsにシステム上のファイルとの対話方法を指示します。 フラグaを使用すると、Node.jsにファイルを上書きせずに追加するように指示します。 フラグを指定しない場合、デフォルトでwに設定されます。フラグが存在しない場合は新しいファイルが作成され、すでに存在する場合はファイルが上書きされます。 ファイルシステムフラグの詳細については、Node.jsのドキュメントをご覧ください。

スクリプトを完成させるには、これらの関数を使用してください。 ファイルの最後に次の強調表示された行を追加します。

node-files / writeFile.js

...
async function addGroceryItem(name, quantity, price) {
  try {
    const csvLine = `\n${name},${quantity},${price}`
    await fs.writeFile('groceries.csv', csvLine, { flag: 'a' });
  } catch (error) {
    console.error(`Got an error trying to write to a file: ${error.message}`);
  }
}

(async function () {
  await openFile();
  await addGroceryItem('eggs', 12, 1.50);
  await addGroceryItem('nutella', 1, 4);
})();

関数を呼び出すには、最初にasync functionを使用してラッパー関数を作成します。 このチュートリアルの執筆時点では、awaitキーワードはグローバルスコープから使用できないため、非同期関数をasync functionでラップする必要があります。 この関数は匿名であることに注意してください。つまり、この関数を識別するための名前がありません。

openFile()およびaddGroceryItem()関数は非同期関数です。 これらの呼び出しを別の関数で囲むことなく、コンテンツの順序を保証することはできません。 作成したラッパーは、asyncキーワードで定義されています。 その関数内で、awaitキーワードを使用して関数呼び出しを注文します。

最後に、async functionの定義は括弧で囲まれています。 これらはJavaScriptに、その中のコードが関数式であることを伝えます。 関数の最後でセミコロンの前の括弧は、関数をすぐに呼び出すために使用されます。 これは、即時呼び出し関数式(IIFE)と呼ばれます。 匿名関数でIIFEを使用することにより、コードが3行のCSVファイルを生成することをテストできます。列ヘッダー、eggsの行、およびnutellaの最後の行です。

CTRL+Xを使用してnanoを保存して終了します。

次に、nodeコマンドを使用してコードを実行します。

node writeFile.js

出力はありません。 ただし、新しいファイルは現在のディレクトリに存在します。

catコマンドを使用して、groceries.csvの内容を表示します。

cat groceries.csv

次の出力が表示されます。

node-files / groceries.csv

name,quantity,price
eggs,12,1.5
nutella,1,4

openFile()を呼び出すと、新しいファイルが作成され、CSVの列見出しが追加されました。 その後のaddGroceryItem()の呼び出しにより、2行のデータが追加されました。

writeFile()機能を使用すると、ファイルを作成および編集できます。 次に、ファイルを削除します。これは、一時ファイルがある場合やハードドライブにスペースを確保する必要がある場合の一般的な操作です。

手順3—unlink()を使用してファイルを削除する

この手順では、fsモジュールのunlink()機能を使用してファイルを削除します。 前のセクションで作成したgroceries.csvファイルを削除するNode.jsスクリプトを作成します。

ターミナルで、このNode.jsモジュールの新しいファイルを作成します。

nano deleteFile.js

次に、非同期deleteFile()関数を作成するコードを記述します。 この関数は、引数としてファイルパスを受け入れ、それをunlink()関数に渡して、ファイルシステムから削除します。

テキストエディタで、次のコードを記述します。

node-files / deleteFile.js

const fs = require('fs').promises;

async function deleteFile(filePath) {
  try {
    await fs.unlink(filePath);
    console.log(`Deleted ${filePath}`);
  } catch (error) {
    console.error(`Got an error trying to delete the file: ${error.message}`);
  }
}

deleteFile('groceries.csv');

unlink()関数は、削除するファイルのファイルパスという1つの引数を受け入れます。

警告: unlink()機能を使用してファイルを削除すると、ファイルはごみ箱に送られません。ごみ箱はファイルシステムから完全に削除されます。 このアクションは元に戻せないため、コードを実行する前にファイルを削除することを確認してください。


nanoを終了し、CTRL+Xと入力してファイルの内容を確実に保存します。

次に、プログラムを実行します。 ターミナルで次のコマンドを実行します。

node deleteFile.js

次の出力が表示されます。

OutputDeleted groceries.csv

ファイルが存在しないことを確認するには、現在のディレクトリでlsコマンドを使用します。

ls

このコマンドは、次のファイルを表示します。

OutputdeleteFile.js   greetings.txt   readFile.js     writeFile.js

これで、unlink()機能でファイルが削除されたことを確認できました。

これまで、ファイルの読み取り、書き込み、編集、および削除の方法を学習しました。 次のセクションでは、関数を使用してファイルを別のフォルダーに移動します。 その機能を学習すると、Node.jsで最も重要なファイル管理タスクを実行できるようになります。

ステップ4—rename()を使用してファイルを移動する

フォルダはファイルを整理するために使用されるため、プログラムでファイルをあるフォルダから別のフォルダに移動できると、ファイル管理が容易になります。 rename()関数を使用して、Node.js内のファイルを移動できます。 この手順では、greetings.txtファイルのコピーを新しいフォルダーに移動します。

Node.jsモジュールをコーディングする前に、いくつかの設定を行う必要があります。 ファイルの移動先となるフォルダを作成することから始めます。 ターミナルで、現在のディレクトリにtest-dataフォルダを作成します。

mkdir test-data

次に、cpコマンドを使用して、最初のステップで使用したgreetings.txtファイルをコピーします。

cp greetings.txt greetings-2.txt

コードを含むJavaScriptファイルを開いて、セットアップを完了します。

nano moveFile.js

Node.jsモジュールで、rename()関数を呼び出すmoveFile()という関数を作成します。 rename()機能を使用する場合は、元のファイルのファイルパスと宛先の場所のパスを指定する必要があります。 この例では、moveFile()関数を使用して、greetings-2.txtファイルをtest-dataフォルダーに移動します。 また、名前をsalutations.txtに変更します。

開いているテキストエディタに次のコードを入力します。

node-files / moveFile.js

const fs = require('fs').promises;

async function moveFile(source, destination) {
  try {
    await fs.rename(source, destination);
    console.log(`Moved file from ${source} to ${destination}`);
  } catch (error) {
    console.error(`Got an error trying to move the file: ${error.message}`);
  }
}

moveFile('greetings-2.txt', 'test-data/salutations.txt');

前述のように、rename()関数は、ソースファイルパスと宛先ファイルパスの2つの引数を取ります。 この関数は、ファイルを他のフォルダに移動したり、現在のディレクトリ内のファイルの名前を変更したり、同時に移動して名前を変更したりできます。 コードでは、ファイルを移動して名前を変更しています。

CTRL+Xを押して、nanoを保存して終了します。

次に、nodeでこのプログラムを実行します。 プログラムを実行するには、次のコマンドを入力します。

node moveFile.js

次の出力が表示されます。

OutputMoved file from greetings-2.txt to test-data/salutations.txt

ファイルが現在のディレクトリに存在しないことを確認するには、lsコマンドを使用できます。

ls

このコマンドは、これらのファイルとフォルダーを表示します。

OutputdeleteFile.js   greetings.txt   moveFile.js     readFile.js     test-data       writeFile.js

これで、lsを使用して、test-dataサブフォルダー内のファイルを一覧表示できます。

ls test-data

移動したファイルが出力に表示されます。

Outputsalutations.txt

これで、rename()関数を使用して、ファイルを現在のディレクトリからサブフォルダーに移動しました。 また、同じ関数呼び出しでファイルの名前を変更しました。

結論

この記事では、Node.jsでファイルを管理するためのさまざまな機能を学びました。 最初に、readFile()を使用してファイルの内容をロードしました。 次に、writeFile()関数を使用して、新しいファイルを作成し、既存のファイルにデータを追加しました。 unlink()機能を使用してファイルを完全に削除してから、rename()を使用してファイルを移動して名前を変更しました。

プログラムでファイルを操作することは、Node.jsの重要な機能です。 プログラムは、ユーザーが使用できるようにファイルを出力する必要がある場合や、常に実行されているとは限らないアプリケーションのデータを保存する必要がある場合があります。 fsモジュールの機能を使用すると、開発者はNode.jsプログラムでのファイルの使用方法を制御できます。

fsモジュールの詳細については、Node.jsのドキュメントをご覧ください。 Node.jsの学習を継続したい場合は、 Node.jsシリーズのコーディング方法に戻るか、Nodeトピックページでプログラミングプロジェクトとセットアップを参照してください。