情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

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

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js