fs.readFileからデータを取得する


296
var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

ログundefined、なぜ?


1
fs.readFileSyncには、Unicode utf8形式のファイルを読み取るための優れた機能もあります。
Praneeth、

NB fs.readFileもそれを行うことができます^以下の私の答えを参照してください
Dominic

回答:


348

@Raynosの発言を詳しく説明すると、定義した関数は非同期コールバックです。すぐには実行されず、ファイルのロードが完了したときに実行されます。readFileを呼び出すと、制御がすぐに返され、コードの次の行が実行されます。したがって、console.logを呼び出すとき、コールバックはまだ呼び出されておらず、このコンテンツはまだ設定されていません。非同期プログラミングへようこそ。

アプローチ例

const fs = require('fs');
// First I want to read the file
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    const content = data;

    // Invoke the next step here however you like
    console.log(content);   // Put all of the code here (not the best solution)
    processFile(content);   // Or put the next step in a function and invoke it
});

function processFile(content) {
    console.log(content);
}

あるいは、レイノスの例が示すように、呼び出しを関数にラップし、独自のコールバックを渡します。(どうやらこれはより良い習慣です)コールバックを受け取る関数で非同期呼び出しをラップする習慣を身につけることで、多くの問題と面倒なコードを節約できます。

function doSomething (callback) {
    // any async callback invokes callback with response
}

doSomething (function doSomethingAfter(err, result) {
    // process the async result
});

2
同期I / Oはその場所にあります—小さなビルドシステムまたはツールを実行している場合は問題ありません。大規模なシステムまたはサーバーアプリでは、ベストプラクティスはそれを回避することです。
RobW 2014年

27
すべてがWebサーバーであるとは限りません。また、サーバーがリクエストの取得を開始する前に、ワンショットコールのメソッドの同期バージョンを使用することについて、恐ろしいことは何もありません。Nodeを使用する人は、それを使用する前にその理由を本当に理解する必要があります。間違いなくそれについて暴言を書く前に。
Erik Reppen、2015年


7
'utf8'追加のパラメータとしてファイル名の後に含める必要があります。そうしないと、バッファが返されます。参照:stackoverflow.com/questions/9168737/...
DollarAkshay

252

これには実際には同期関数があります:

http://nodejs.org/api/fs.html#fs_fs_readfilesync_filename_encoding

非同期

fs.readFile(filename, [encoding], [callback])

ファイルの内容全体を非同期で読み取ります。例:

fs.readFile('/etc/passwd', function (err, data) {
  if (err) throw err;
  console.log(data);
});

コールバックには2つの引数(err、data)が渡されます。ここで、dataはファイルの内容です。

エンコーディングが指定されていない場合、生のバッファが返されます。


同期

fs.readFileSync(filename, [encoding])

fs.readFileの同期バージョン。filenameという名前のファイルの内容を返します。

エンコーディングが指定されている場合、この関数は文字列を返します。それ以外の場合は、バッファを返します。

var text = fs.readFileSync('test.md','utf8')
console.log (text)

簡単な質問、readFileの同期バージョンで返されるバッファーの用途は何ですか?ファイルを同期的に読み取り、エンコーディングを渡さない場合、バッファーを出力しますが、これをどのように使用できますか?ありがとうございました。
encodingbbq 2013

12
最近これを経験しました。バッファがであるとしましょうdataif (Buffer.isBuffer( data){ result = data.toString('utf8'); }これで、バッファーが読み取り可能なテキストに変換されました。これは、プレーンテキストファイルを読み取ったり、ファイルをフォーマットタイプに対してテストしたりするのに適しています。たとえば、JSONファイルかどうかを確認するためにtry / catchを実行できます。ただし、バッファがテキストに変換された後のみ。詳細については、ここを参照してください。nodejs.org
Logan

また、私が知る限り、バッファはオクテットストリームであり、「ピース単位」でデータを送信するのに適しています。あなたはバッファがのようなものであることを見たはずAF 42 F1です。クライアント/サーバー/クライアント通信に非常に実用的です。
ローガン

113
function readContent(callback) {
    fs.readFile("./Index.html", function (err, content) {
        if (err) return callback(err)
        callback(null, content)
    })
}

readContent(function (err, content) {
    console.log(content)
})

6
どうもありがとう
ございました。15点満点

こんにちは、コードの最初の行function readContent(callback)、はcallback予約語ですか?つまり、これはカスタム関数のコールバックを実装する標準的な方法ですか?ノードの学習を開始しました。
アマルアントニー

3
こんにちは、アマル。コールバックは、単に彼の関数に渡される引数で、それは可能性がありevent、またはcなど、任意の名前あなた-それはJavascriptの予約語ではない、と私は同じことがNode.js.まで伸び引き受けます
RealDeal_EE'18

readContent(function (err, content)関数をパラメーターとして使用すると、構文エラーが発生します。
monsto 2015年

66

ES7でPromiseを使用する

mz / fsでの非同期使用

このmzモジュールは、コアノードライブラリの保証されたバージョンを提供します。それらを使用するのは簡単です。最初にライブラリをインストールします...

npm install mz

その後...

const fs = require('mz/fs');
fs.readFile('./Index.html').then(contents => console.log(contents))
  .catch(err => console.error(err));

あるいは、非同期関数でそれらを書くことができます:

async function myReadfile () {
  try {
    const file = await fs.readFile('./Index.html');
  }
  catch (err) { console.error( err ) }
};

6
これは未来であり、みんなから高く評価されるべきです:)ありがとう
PirateApp

2
面白いですね。1つのタイプミス: 'console.error(catch)'は 'console.error(err)'になるはずです)。
philwalk 2017年

2
パッケージを追加したくない場合は、以下の
@doctorlee

18
var data = fs.readFileSync('tmp/reltioconfig.json','utf8');

これを使用して、表示出力をバッファーとしてエンコードせずに、ファイルを同期的に呼び出します。


2
あなたはキックにかなり印刷のために、コードブロックの前に空白行を必要としています。
royhowie

ブリーフィング&ベスト!
ダイヤモンド

13

この行は機能します

const content = fs.readFileSync('./Index.html', 'utf8');
console.log(content);

1
7年経過した:) fs.readFileSyncは同期メソッドなので、awaitそこに必要はありません。Awaitは、同期コードと同様の構文で非同期コードを記述したい場合に、promisenodejs.org/api/fs.html#fs_fs_promises_api)で役立ちます。
karaxuna

@karaxuna、ええ。削除されました。今日、このケースに遭遇しただけで、上記のコードを使用して解決しました。
アラビン

1
これが最も簡単な答えです。非同期が必要ない場合、なぜコールバック、非同期/待機などを使用して、非同期バージョンと混合するのですか?これが方法です。
アヒルのマスター

8
const fs = require('fs')
function readDemo1(file1) {
    return new Promise(function (resolve, reject) {
        fs.readFile(file1, 'utf8', function (err, dataDemo1) {
            if (err)
                reject(err);
            else
                resolve(dataDemo1);
        });
    });
}
async function copyFile() {

    try {
        let dataDemo1 = await readDemo1('url')
        dataDemo1 += '\n' +  await readDemo1('url')

        await writeDemo2(dataDemo1)
        console.log(dataDemo1)
    } catch (error) {
        console.error(error);
    }
}
copyFile();

function writeDemo2(dataDemo1) {
    return new Promise(function(resolve, reject) {
      fs.writeFile('text.txt', dataDemo1, 'utf8', function(err) {
        if (err)
          reject(err);
        else
          resolve("Promise Success!");
      });
    });
  }

5
答えにコードを入れるだけではなく、なぜそれが違うのか、それがどのように問題を解決するのかを説明してください。
Studocwho

@doctorleeこれは実際には外部ライブラリなしで動作します。必ず説明が必要です。
Ashutosh Chamoli

7

同期および非同期ファイルの読み取り方法:

//fs module to read file in sync and async way

var fs = require('fs'),
    filePath = './sample_files/sample_css.css';

// this for async way
/*fs.readFile(filePath, 'utf8', function (err, data) {
    if (err) throw err;
    console.log(data);
});*/

//this is sync way
var css = fs.readFileSync(filePath, 'utf8');
console.log(css);

ノードのチートはread_fileで利用可能です


7

言ったようにfs.readFile、非同期アクションです。つまり、ノードにファイルを読み取るように指示するときは、しばらく時間がかかることを考慮する必要があります。その間、ノードは次のコードを実行し続けました。あなたのケースではそれはです:console.log(content);

これは、長い旅行(大きなファイルの読み取りなど)のためにコードの一部を送信するようなものです。

私が書いたコメントを見てください:

var content;

// node, go fetch this file. when you come back, please run this "read" callback function
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});

// in the meantime, please continue and run this console.log
console.log(content);

これが、contentログに記録しても空のままである理由です。ノードはまだファイルのコンテンツを取得していません。

これはconsole.log(content)、コールバック関数内での直後に移動することで解決できますcontent = data;。このようにして、ノードがファイルの読み取りを完了しcontent、値を取得した後にログを確認できます。


6

組み込みのpromisifyライブラリ(Node 8+)を使用して、これらの古いコールバック関数をよりエレガントにします。

const fs = require('fs');
const util = require('util');

const readFile = util.promisify(fs.readFile);

async function doStuff() {
  try {
    const content = await readFile(filePath, 'utf8');
    console.log(content);
  } catch (e) {
    console.error(e);
  }
}

単一行にすることができますconst doStuff = async (filePath) => fs.readFileSync(filePath, 'utf8');。util.promisifyラップは不要です。
rab

1
同期バージョンを使用しないことがこれのポイントであり、それを呼び出すときにエラーを処理する必要があります
Dominic

4
var fs = require('fs');
var path = (process.cwd()+"\\text.txt");

fs.readFile(path , function(err,data)
{
    if(err)
        console.log(err)
    else
        console.log(data.toString());
});

2
var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

これは、ノードが非同期であり、読み取り関数を待機せず、プログラムが起動するとすぐに値が未定義としてコンソールに表示されるためです。コンテンツ変数に値が割り当てられていないため、実際にはtrueです。処理するには、promise、ジェネレータなどを使用できます。promiseをこのように使用できます。

new Promise((resolve,reject)=>{
    fs.readFile('./index.html','utf-8',(err, data)=>{
        if (err) {
            reject(err); // in the case of error, control flow goes to the catch block with the error occured.
        }
        else{
            resolve(data);  // in the case of success, control flow goes to the then block with the content of the file.
        }
    });
})
.then((data)=>{
    console.log(data); // use your content of the file here (in this then).    
})
.catch((err)=>{
    throw err; //  handle error here.
})

2

以下は、asyncラップまたはプロミスthenチェーンで機能する関数です。

const readFileAsync =  async (path) => fs.readFileSync(path, 'utf8');

1

あなたはファイルを読むことができます

var readMyFile = function(path, cb) {
      fs.readFile(path, 'utf8', function(err, content) {
        if (err) return cb(err, null);
        cb(null, content);
      });
    };

さらに、ファイルに書き込むことができます。

var createMyFile = (path, data, cb) => {
  fs.writeFile(path, data, function(err) {
    if (err) return console.error(err);
    cb();
  });
};

そしてそれを一緒にチェーンします

var readFileAndConvertToSentence = function(path, callback) {
  readMyFile(path, function(err, content) {
    if (err) {
      callback(err, null);
    } else {
      var sentence = content.split('\n').join(' ');
      callback(null, sentence);
    }
  });
};

1

大まかに言えば、本来非同期であるnode.jsを扱っています。

私たちが非同期について話すとき、私たちは何か他のものを扱う間に情報やデータを行うか、処理することを話します。パラレルとは同義ではありません。注意してください。

あなたのコード:

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
});
console.log(content);

サンプルでは、​​基本的にconsole.log部分が最初に実行されるため、変数 'c​​ontent'は未定義です。

出力が本当に必要な場合は、代わりに次のようにします。

var content;
fs.readFile('./Index.html', function read(err, data) {
    if (err) {
        throw err;
    }
    content = data;
    console.log(content);
});

これは非同期です。慣れるのは難しいですが、それはそれです。繰り返しますが、これは非同期とは何かについての大まかではありますが迅速な説明です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.