Node.jsはその柔軟性と効率性から、ファイルの操作においても強力な機能を提供しています。
本記事ではNode.jsのfs
(File System)モジュールを中心に、ファイルの作成、削除、書き込み、読み込み、そして存在チェックなど、幅広いファイル操作に関わる要素を掘り下げていきます。
encoding、writeFile
、readFile
、existsSync
、unlink
、mkdir
、rmdir
、createReadStream
、createWriteStream
、そしてchunk
といった、より高度で具体的なトピックにも焦点を当てます。
Node.jsのファイル操作は、単なるファイルの読み書き以上のものであり、効率的なストリーム処理やデータのエンコーディングにも深く関わっています。
各要素を理解し適切に活用することは、実用的なアプリケーションの開発において不可欠です。
そこで本記事ではこれらの要素について実践的な例を交えながら解説し、Node.jsを使ったファイル操作の幅広い可能性に迫っていきます。
Node.jsでファイル操作をする方法
Node.jsにはfsというモジュールがあり、fsをインポートすることでファイルの読み込み、書き込みが簡単にできるようになります。
まずは定数fsを用意してモジュールのインポートをします。
const fs = require('fs');
例えばテキストファイルを読み込む場合には以下のように書きます。
const fs = require('fs');
// ここを追加
fs.readFile('./file-basic/example.txt', (err, data) => {
if (err) {
console.log(err);
}
console.log(data.toString());
});
readFileというメソッドが使用できて、第一引数にファイルのパスを書いて第二引数に実行したい内容を書くだけです。
今回はコンソールに表示するようにしています。
読み込んだテキストファイルの内容を上書きするときにはwriteFileというメソッドで第二引数にテキストなどデータを書く形になります。
const fs = require('fs');
fs.readFile('./file-basic/example.txt', (err, data) => {
if (err) {
console.log(err);
}
console.log(data.toString());
});
// ここを追加
fs.writeFile('./file-basic/example.txt', '更新しました', (err) => {
if (err) {
console.log(err);
}
console.log('written');
});
またファイルを削除するときにはunlinkというメソッドを使用します。
const fs = require('fs');
fs.readFile('./file-basic/example.txt', (err, data) => {
if (err) {
console.log(err);
}
console.log(data.toString());
});
fs.writeFile('./file-basic/example.txt', '更新しました', (err) => {
if (err) {
console.log(err);
}
console.log('written');
});
// ここを追加
fs.unlink('./file-basic/example1.txt', (err) => {
if (err) {
console.log(err);
}
console.log('deleted');
});
readFileもwriteFileもunlinkも役割が違うだけで書き方は似ていますよね。
実務ではいきなりファイル作成、削除するというより「同じ名前のファイルがないか確認する」ことが求められます。
existsSyncメソッドというものがあり、引数に指定したパスやファイル名が存在する場合にはTrue, 存在しない場合にはFalseを返します。
そのため「ファイルがすでにあれば削除して、なければ作成する」という作業は以下のように書きます。
// ファイルがすでにあれば削除して、なければ作成する
if (fs.existsSync('./file-basic/example.txt')) {
fs.unlink('./file-basic/example1.txt', (err) => {
if (err) {
console.log(err);
}
console.log('deleted');
});
} else {
fs.writeFile('./file-basic/example.txt', '作成しました', (err) => {
if (err) {
console.log(err);
}
console.log('written');
});
}
existsSyncというメソッドはファイル名ではなくフォルダ名を指定しても同じ効果が得られます。
ちなみにフォルダの場合、作成はmkdirメソッドで削除はrmdirメソッドという名前に変わります。
// ディレクトリの作成、削除も同じ
if (fs.existsSync('./file-basic/assets')) {
fs.rmdir('./file-basic/assets', (err) => {
if (err) {
console.log(err);
}
console.log('removed');
});
} else {
fs.mkdir('./file-basic/assets', (err) => {
if (err) {
console.log(err);
}
console.log('created');
});
}
Node.jsでファイル操作する際に登場するストリームとは?
Node.jsにおけるファイル操作の基本は解説したところで「ストリーム」というキーワードを聞かれるかもしれません。
Netflixなどのストリーミングサービスと同じようなイメージで大丈夫です。
いわゆるサイズの大きいファイルは読み込むのに時間がかかるので、細切れで少しずつ読み込む技術があり、その総称をストリームと呼びます。
重たいファイルも前章でインポートしたfsで、読み込みはcreateReadStreamというメソッドで、書き込みはcreateWriteStreamというメソッドで対応させることが可能です。
const fs = require('fs');
// 重たいファイルの読み込み
const read = fs.createReadStream('./stream-basic/example.txt');
// 重たいファイルの書き込み
const write = fs.createWriteStream('./stream-basic/example1.txt');
また読み込み、書き込みともにonというメソッドを使用することになっていて、第一引数にdataというイベント名を指定して第二引数に処理内容を書きます。
例えば10万文字を超えるテキストを読み込んでみます。
const fs = require('fs');
const read = fs.createReadStream('./stream-basic/example.txt');
read.on('data', (chunk) => {
console.log(chunk.toString());
});
読み込む処理で登場するtoString()というメソッドは前章と変わらないのですが、こちらはデータから人間が読める文字に変換してくれています。
試しにtoStringなしでコンソールに表示させて見ると、以下のような記号の羅列が表示されるはずです。
こちらはバイナリーデータと言ってコンピュータが理解できる文字のことです。
ファイルはバイナリーデータとして保存されているためです。
バイナリーデータで見るとストリームがわかりやすくなります。
以下のように書いて実行してみます。
const fs = require('fs');
const read = fs.createReadStream('./stream-basic/example.txt');
read.on('data', (chunk) => {
// ここを変更
console.log('----');
console.log(chunk);
});
途中で「—-」の文字が何回か表示されているはずです。
こちらからも通常のconsole.log()を実行しているように見えてデータを細かく区切っていることがわかります。