jsonファイルの値を更新してnode.jsを介して保存する方法


84

jsonファイルの値を更新してnode.jsを介して保存するにはどうすればよいですか?私はファイルの内容を持っています:

var file_content = fs.readFileSync(filename);
var content = JSON.parse(file_content);
var val1 = content.val1;

ここで、の値を変更val1してファイルに保存します。

回答:


127

これを非同期で行うのは非常に簡単です。スレッドのブロックが心配な場合(可能性が高い)に特に役立ちます。

const fs = require('fs');
const fileName = './file.json';
const file = require(fileName);
    
file.key = "new value";
    
fs.writeFile(fileName, JSON.stringify(file), function writeJSON(err) {
  if (err) return console.log(err);
  console.log(JSON.stringify(file));
  console.log('writing to ' + fileName);
});

注意点は、jsonが1行でファイルに書き込まれ、プリ​​ティファイされていないことです。例:

{
  "key": "value"
}

になります...

{"key": "value"}

これを回避するには、次の2つの引数を追加するだけです。 JSON.stringify

JSON.stringify(file, null, 2)

null-置換機能を表します。(この場合、プロセスを変更したくありません)

2 -インデントするスペースを表します。


50
//change the value in the in-memory object
content.val1 = 42;
//Serialize as JSON and Write it to a file
fs.writeFileSync(filename, JSON.stringify(content));

6
全体として、これがノードの主な焦点であるため、非同期書き込みを使用する方が良いでしょう。もちろん、周囲のコードを見ずに、決定的な答えを出すのは難しいでしょう。書き込みが完了するまで他に何も起こらないことを絶対に確信する必要がない限り、本当に同期が必要になる可能性はほとんどありません。さらに、もちろん、ファイルの書き込みが成功することを確信できないため、これにはエラーチェッカーが必要です。
ジュリアンナイト

4
非同期と同期は、どのコンテキストで何をしているかによって異なります。これがネットワークサービスにある場合は、非同期が必要です。コマンドラインユーティリティの場合、ほとんどの単純なケースでは同期が適切なパラダイムですが、「非同期の方が優れている」というひざまずくだけでは正しくありません。私のスニペットは、コンテキストのOPスニペットに基づいています。問題はエラー処理についてでもありません。ファイルの書き込みが失敗した場合、スタックトレースで終了することは、それから回復するためにできることはあまりないため、妥当なデフォルトの動作です。
Peter Lyons

ノードはループベースであるため、ほとんどの場合、非同期の方が優れているため、ループをブロックしません。これはひざまずく反応ではなく、ノード開発の標準的な方法です。要件にもよると言ったのですが、Qはコマンドラインについて何も言っていないと思いますか?また、一般に、これがより大きなコードセットの一部である場合(OPによって明確化されていない場合)、エラー処理は常にスマートでベストプラクティスです。スタックトレースをダンプすることは、開発者にとっては問題ありませんが、他のすべての人にとってはがらくたです。
ジュリアンナイト

22
asyncは並行性の手法です。並行性が必要な場合は、ノードが正しく機能するために非同期が必要です(「より良い」ではありません)。並行性がない場合は、非同期は必要ありません。重要なのは、非同期があなたのために何をするのか、そしてその理由を実際に理解する必要があるということです。理由もなく本質的に「優れている」わけではなく、「ベストプラクティス」として記憶する必要はありません。OPがJSONファイルを変更して終了するコマンドラインユーティリティを作成している場合、同時実行は必要ないため、非同期は理由もなくコードを複雑にします。
Peter Lyons

ノードコマンドラインツールを構築しています。同期書き込みされていない場合、ツールの出力が次のツールにチェーンされるときにファイルがロックされる可能性があります。同期を使用する非常に正当な理由があります。そして、非同期を使用する正当な理由。
TamusJRoyce

3

前の回答に加えて、書き込み操作用のファイルパスディレクトリを追加します

 fs.writeFile(path.join(__dirname,jsonPath), JSON.stringify(newFileData), function (err) {}

2
// read file and make object
let content = JSON.parse(fs.readFileSync('file.json', 'utf8'));
// edit or add property
content.expiry_date = 999999999999;
//write file
fs.writeFileSync('file.json', JSON.stringify(content));

0

jsonコレクションにアイテムを追加したい方のために

function save(item, path = './collection.json'){
    if (!fs.existsSync(path)) {
        fs.writeFile(path, JSON.stringify([item]));
    } else {
        var data = fs.readFileSync(path, 'utf8');  
        var list = (data.length) ? JSON.parse(data): [];
        if (list instanceof Array) list.push(item)
        else list = [item]  
        fs.writeFileSync(path, JSON.stringify(list));
    }
}

0

同期(ブロッキング)関数は他の同時操作を保持するため、使用しないことを強くお勧めします。代わりに、非同期のfs.promisesを使用してください

const fs = require('fs').promises

const setValue = (fn, value) => 
  fs.readFile(fn)
    .then(body => JSON.parse(body))
    .then(json => {
      // manipulate your data here
      json.value = value
      return json
    })
    .then(json => JSON.stringify(json))
    .then(body => fs.writeFile(fn, body))
    .catch(error => console.warn(error))

setValue保留中のpromiseを返すRemeberの場合は、.then関数を使用するか、非同期関数内でawait演算子を使用する必要があります。

// await operator
await setValue('temp.json', 1)           // save "value": 1
await setValue('temp.json', 2)           // then "value": 2
await setValue('temp.json', 3)           // then "value": 3

// then-sequence
setValue('temp.json', 1)                 // save "value": 1
  .then(() => setValue('temp.json', 2))  // then save "value": 2
  .then(() => setValue('temp.json', 3))  // then save "value": 3

0

タスク完了後にデータを保存する

fs.readFile("./sample.json", 'utf8', function readFileCallback(err, data) {
        if (err) {
          console.log(err);
        } else {
          fs.writeFile("./sample.json", JSON.stringify(result), 'utf8', err => {
            if (err) throw err;
            console.log('File has been saved!');
          });
        }
      });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.