Node.jsでテキストファイルやバイナリファイルのデータを読み込む
2016/11/26
目次
テキストファイルやバイナリファイルのデータを読み込むには非同期的に読み込む方法と同期的に読み込む方法とストリームを使用して読み込む方法の3つがあります。
ストリームとは?
なお、テキストファイルのデータの読み込みにおいて対応している文字コードはバッファが対応している文字コードと同じです。
対応している文字コードに関しては下の記事の「文字コード」の項を参照してください。
文字コード
非同期的な読み込み
テキストファイルやバイナリファイルのデータを非同期的に読み込むにはfs.readFile
関数を使用します。
var fs = require('fs');
fs.readFile('xxx', {
encoding: 'utf-8'
}, function (err, data) {
});
//or
fs.readFile('xxx', 'utf-8', function (err, data) {
});
//or
fs.readFile('xxx', function (err, data) {
});
第1引数にファイルのパスを指定します。
第2引数にオプションをオブジェクトとして指定します。この引数は指定しなくても構いません。
オプションには下のようなものがあります。
encoding
・・・テキストファイルの文字コードを指定します。バイナリファイルのデータを読み込む場合には指定しません。
ただし、第2引数にはオプションをオブジェクトとして指定するのではなく、テキストファイルの文字コードのみを直接指定することもできます。
第3引数にコールバック関数を指定します。この関数の第1引数はエラーオブジェクトであり、第2引数はファイルのデータです。
このデータは第2引数の文字コードを指定した場合には文字列となり、指定しなかった場合にはバッファとなります。
なお、ファイルが存在しない場合にはエラーが発生します。
同期的な読み込み
テキストファイルやバイナリファイルのデータを同期的に読み込むにはfs.readFileSync
関数を使用します。
var data = fs.readFileSync('xxx', {
encoding: 'utf-8'
});
//or
var data = fs.readFileSync('xxx', 'utf-8');
//or
var data = fs.readFileSync('xxx');
第1引数にファイルのパスを指定します。
第2引数にオプションをオブジェクトとして指定します。この引数は指定しなくても構いません。このオプションはfs.readFile
関数の第2引数のオプションと同じです。
返り値としてファイルのデータが得られます。
このデータは第2引数の文字コードを指定した場合には文字列となり、指定しなかった場合にはバッファとなります。
なお、ファイルが存在しない場合にはエラーが発生します。
ストリームを使用した読み込み
ストリームを使用してテキストファイルやバイナリファイルのデータを読み込むにはfs.createReadStream
関数を使用します。
var rs = fs.createReadStream('xxx', {
encoding: 'utf-8',
start: 100,
end: 200
});
//or
var rs = fs.createReadStream('xxx', 'utf-8');
//or
var rs = fs.createReadStream('xxx');
第1引数にファイルのパスを指定します。
第2引数にオプションをオブジェクトとして指定します。この引数は指定しなくても構いません。
オプションには下のようなものがあります。
encoding
・・・テキストファイルの文字コードを指定します。バイナリファイルのデータを読み込む場合には指定しません。start
・・・読み込みの開始位置をバイト単位で指定します。end
・・・読み込みの終了位置をバイト単位で指定します。
ただし、第2引数にはオプションをオブジェクトとして指定するのではなく、テキストファイルの文字コードのみを直接指定することもできます。
返り値としてファイルのデータを読み込む読み込みストリームが得られます。
なお、ファイルが存在しない場合にはエラーが発生します。
使い分け
原則的にはfs.readFile
関数かfs.createReadStream
関数を使用するべきであり、特に理由がないならfs.readFileSync
関数は使用するべきではありません。
これは、ファイルへのアクセスは非常に時間の掛かる処理であるためです。ファイルへのアクセスを同期的に行うとアクセスが完了するまでプログラムは待機状態となり、他の処理を行うことができません。長い時間プログラムが待機状態になると様々な問題を引き起こす可能性があります(このような現象をスターベーションと言います)。
スターベーションとは?
また、fs.readFile
関数やfs.readFileSync
関数はファイルのデータ全体をメモリにロードします。そのため、ファイルのサイズが非常に大きい場合には使用するべきではありません。そのような場合にはfs.createReadStream
関数を使用するべきです。
サンプルコード1
fs.readFile
関数の使用例です。
3つ目のコマンドライン引数として与えられたテキストファイルのデータを非同期的に読み込み、標準出力に出力します。
fs-readfile-text.js
var fs = require('fs');
if (process.argv.length < 3) {
console.error('lack argument.');
process.exit(1);
}
fs.readFile(process.argv[2], 'utf-8', function (err, data) {
if (err) {
console.error(err);
process.exit(1);
}
else {
process.stdout.write(data);
}
});
実行結果
現在のフォルダにはtextfile.txt
という名称のテキストファイルが存在しています(文字コードはUTF-8
です)。
C:\work\node>type textfile.txt
これはテキストファイルの内容です。
このテキストファイルを3つ目のコマンドライン引数に指定してコードを実行すると正しく内容が出力されます。
C:\work\node>node fs-readfile-text.js textfile.txt
これはテキストファイルの内容です。
存在しないテキストファイルやフォルダを指定した場合にはエラーが発生します。
C:\work\node>node fs-readfile-text.js textfile2.txt
{ [Error: ENOENT: no such file or directory, open 'C:\work\node\textfile2.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'C:\\work\\node\\textfile2.txt' }
C:\work\node>node fs-readfile-text.js C:\work\node
{ [Error: EISDIR: illegal operation on a directory, read] errno: -4068, code: 'EISDIR', syscall: 'read' }
なお、テキストファイルの文字コードがUTF-8
でない場合には下のように文字化けします。
C:\work\node>type textfile.txt
����̓e�L�X�g�t�@�C���̓�e�ł��B
C:\work\node>node fs-readfile.js textfile.txt
�����̓e�L�X�g�t�@�C���̓��e�ł��B
サンプルコード2
fs.readFileSync
関数の使用例です。
3つ目のコマンドライン引数として与えられたテキストファイルのデータを同期的に読み込み、標準出力に出力します。
fs-readfilesync-text.js
var fs = require('fs');
if (process.argv.length < 3) {
console.error('lack argument.');
process.exit(1);
}
var data = '';
try {
data = fs.readFileSync(process.argv[2], 'utf-8');
}
catch (err) {
console.error(err);
process.exit(1);
}
process.stdout.write(data);
実行結果
現在のフォルダにはtextfile.txt
という名称のテキストファイルが存在しています(文字コードはUTF-8
です)。
C:\work\node>type textfile.txt
これはテキストファイルの内容です。
このテキストファイルを3つ目のコマンドライン引数に指定してコードを実行すると正しく内容が出力されます。
C:\work\node>node fs-readfilesync-text.js textfile.txt
これはテキストファイルの内容です。
存在しないテキストファイルやフォルダを指定した場合にはエラーが発生します。
C:\work\node>node fs-readfilesync-text.js textfile2.txt
{ [Error: ENOENT: no such file or directory, open 'C:\work\node\textfile2.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'C:\\work\\node\\textfile2.txt' }
C:\work\node>node fs-readfilesync-text.js C:\work\node
{ [Error: EISDIR: illegal operation on a directory, read] errno: -4068, code: 'EISDIR', syscall: 'read' }
なお、テキストファイルの文字コードがUTF-8
でない場合には下のように文字化けします。
C:\work\node>type textfile.txt
����̓e�L�X�g�t�@�C���̓�e�ł��B
C:\work\node>node fs-readfilesync-text.js textfile.txt
�����̓e�L�X�g�t�@�C���̓��e�ł��B
サンプルコード3
fs.createReadStream
関数の使用例です。
3つ目のコマンドライン引数として与えられたテキストファイルのデータをストリームを使用して読み込み、標準出力に出力します。
fs-createreadstream.js
var fs = require('fs');
if (process.argv.length < 3) {
console.error('lack argument.');
process.exit(1);
}
try {
var rs = fs.createReadStream(process.argv[2], 'utf-8');
rs.on('data', function (data) {
process.stdout.write(data);
});
rs.on('error', function (err) {
console.error(err);
process.exit(1);
});
}
catch (err) {
console.error(err);
process.exit(1);
}
実行結果
現在のフォルダにはtextfile.txt
という名称のテキストファイルが存在しています(文字コードはUTF-8
です)。
C:\work\node>type textfile.txt
これはテキストファイルの内容です。
このテキストファイルを3つ目のコマンドライン引数に指定してコードを実行すると正しく内容が出力されます。
C:\work\node>node fs-createreadstream.js textfile.txt
これはテキストファイルの内容です。
存在しないテキストファイルやフォルダを指定した場合にはエラーが発生します。
C:\work\node>node fs-createreadstream.js textfile2.txt
{ [Error: ENOENT: no such file or directory, open 'C:\work\node\textfile2.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'C:\\work\\node\\textfile2.txt' }
C:\work\node>node fs-createreadstream.js C:\work\node
{ [Error: EISDIR: illegal operation on a directory, read] errno: -4068, code: 'EISDIR', syscall: 'read' }
なお、テキストファイルの文字コードがUTF-8
でない場合には下のように文字化けします。
C:\work\node>type textfile.txt
����̓e�L�X�g�t�@�C���̓�e�ł��B
C:\work\node>node fs-createreadstream.js textfile.txt
�����̓e�L�X�g�t�@�C���̓��e�ł��B
関連
