Dengan menggunakan Node.JS, bagaimana cara membaca file JSON ke dalam memori (server)?

618

Latar Belakang

Saya melakukan beberapa eksperimen dengan Node.js dan ingin membaca objek JSON, baik dari file teks atau file .js (yang lebih baik ??) ke dalam memori sehingga saya dapat mengakses objek itu dengan cepat dari kode. Saya menyadari bahwa ada hal-hal seperti Mongo, Alfred, dll di luar sana, tetapi bukan itu yang saya butuhkan saat ini.

Pertanyaan

Bagaimana cara membaca objek JSON dari file teks atau js dan ke memori server menggunakan JavaScript / Node?

Matt Cashatt
sumber
1
apa yang Anda sebut memori server? skrip nodejs Anda akan berfungsi selama Anda membuatnya, tetapi Anda harus menyimpan data di suatu tempat kecuali Anda membuat skrip nodejs tetap.
mpm

Jawaban:

1205

Sinkronkan:

var fs = require('fs');
var obj = JSON.parse(fs.readFileSync('file', 'utf8'));

Async:

var fs = require('fs');
var obj;
fs.readFile('file', 'utf8', function (err, data) {
  if (err) throw err;
  obj = JSON.parse(data);
});
mihai
sumber
15
Saya pikir JSON.parse sinkron, langsung dari v8, yang berarti bahkan dengan cara Async, orang harus berhati-hati dengan file JSON besar. karena itu akan mengikat simpul.
Sean_A91
25
Demi kelengkapan. Mereka ada npm yang disebut jsonfile .
Stefan
5
Saya tidak percaya sulit menemukan hal sederhana ini. Setiap jawaban yang saya dapatkan dari google melakukan HTTPRequest atau menggunakan JQuery atau melakukannya di browser
juliangonzalez
6
dua poin: (1) Jawaban sinkron seharusnya let imported = require("file.json"). (2) JSON.parse harus asinkron, karena saya menggunakan kode ini untuk memuat file JSON 70mb ke dalam memori sebagai objek. Dibutuhkan milidetik dengan cara ini, tetapi jika saya gunakan require(), itu chugs .
Kyle Baker
8
Untuk orang-orang yang menemukan jawaban ini pada tahun 2019 dan seterusnya, Node.js telah memiliki dukungan json asli untuk banyak, banyak versi melalui require, dengan jawaban ini tidak lagi berlaku jika Anda hanya ingin memuat file json. Cukup gunakan let data = require('./yourjsonfile.json')dan pergilah (dengan catatan buku bahwa jika kinerja yang dibutuhkan memengaruhi kode Anda, Anda memiliki masalah jauh di luar "ingin memuat file .json")
Mike 'Pomax' Kamermans
392

Cara termudah yang saya temukan untuk melakukan ini adalah dengan hanya menggunakan requiredan path ke file JSON Anda.

Misalnya, Anda memiliki file JSON berikut.

test.json

{
  "firstName": "Joe",
  "lastName": "Smith"
}

Anda kemudian dapat dengan mudah memuat ini dalam aplikasi node.js Anda menggunakan require

var config = require('./test.json');
console.log(config.firstName + ' ' + config.lastName);
Travis Tidwell
sumber
35
Hanya agar orang tahu, dan jika saya ingat dengan benar, requiredalam node berjalan secara sinkron. Menyelam jauh di sini
prasanthv
@ Ram Ini berfungsi untuk saya mungkin lokasi Anda test.jsonakan berbeda dari contohnya. Saya menggunakannode 5.0
guleria
18
Masalah / manfaat lain dengan metode tersebut adalah fakta bahwa data yang diperlukan di-cache kecuali Anda secara khusus menghapus contoh di-cache
magicode118
13
"Wajib" dimaksudkan untuk digunakan untuk memuat modul atau file konfigurasi yang Anda gunakan sepanjang umur aplikasi Anda. sepertinya tidak tepat untuk menggunakan ini untuk memuat file.
Yaki Klein
2
Saya akan mengatakan ini berpotensi ancaman keamanan. Jika file json yang Anda muat mengandung kode JS, apakah requireitu akan menjalankan kode itu? Jika demikian maka Anda benar-benar perlu mengontrol dari mana file json Anda berasal atau penyerang dapat menjalankan kode berbahaya pada mesin Anda.
sokkyoku
57

Asynchronous ada karena suatu alasan! Melempar batu ke @mihai

Jika tidak, berikut adalah kode yang ia gunakan dengan versi asinkron:

// Declare variables
var fs = require('fs'),
    obj

// Read the file and send to the callback
fs.readFile('path/to/file', handleFile)

// Write the callback function
function handleFile(err, data) {
    if (err) throw err
    obj = JSON.parse(data)
    // You can now play with your datas
}
Florian Margaine
sumber
9
setuju :), menambahkan async juga
mihai
1
Hebat :-) Saya tidak suka inback panggilan balik, itu bisa menyebabkan mimpi buruk callback yang saya lebih suka hindari.
Florian Margaine
9
Itu ada karena suatu alasan .. kecuali jika Anda menginginkannya secara sinkron.
Matt Stephens
40

Setidaknya di Node v8.9.1, Anda bisa melakukannya

var json_data = require('/path/to/local/file.json');

dan akses semua elemen objek JSON.

Alex Eftimiades
sumber
5
Pendekatan ini memuat file hanya sekali. Jika Anda akan mengubah file.jsonsetelah baru membutuhkan (tanpa memulai kembali program) data akan dari memuat pertama. Saya tidak punya sumber untuk mendukung ini, tapi saya punya ini di aplikasi yang saya bangun
Lukas Ignatavičius
Jawaban Anda sangat tidak lengkap. Apa yang membuat Anda adalah objek, dan bahkan tidak repot untuk mengimplementasikan tostring ().
David A. Gray
3
@ DavidA.Gray Pertanyaannya ingin dapat mengakses objek sebagai objek, bukan sebagai string. Selain dari masalah tunggal Lukas menyebutkan jawaban ini baik-baik saja.
mikemaccana
2
Menggunakan mengharuskan juga akan mengeksekusi kode arbitrer dalam file. Metode ini tidak aman dan saya akan merekomendasikan untuk tidak melakukannya.
spoulson
16

Di Node 8 Anda dapat menggunakan built-in util.promisify()untuk secara asinkron membaca file seperti ini

const {promisify} = require('util')
const fs = require('fs')
const readFileAsync = promisify(fs.readFile)

readFileAsync(`${__dirname}/my.json`, {encoding: 'utf8'})
  .then(contents => {
    const obj = JSON.parse(contents)
    console.log(obj)
  })
  .catch(error => {
    throw error
  })
JP
sumber
3
.readFilesudah async, jika Anda mencari versi sinkronisasi, namanya .readFileSync.
Aternus
Jika Anda ingin menggunakan janji, ada juga fs/promisespada Node 10. Catatan: API adalah eksperimental: nodejs.org/api/fs.html#fs_fs_promises_api
aboutaaron
@Aternus .readFiletidak sinkron , tetapi tidak async. Artinya, fungsi ini tidak didefinisikan dengan asynckata kunci, juga tidak mengembalikan Janji, jadi Anda tidak dapat melakukannyaawait fs.readFile('whatever.json');
Kip
@ Kip, bagaimana dengan CodeSandBox?
Aternus
7

menggunakan node-fs-extra (async tunggu)

const readJsonFile = async () => {
  try {
    const myJsonObject = await fs.readJson('./my_json_file.json');
    console.log(myJsonObject);
  } catch (err) {
    console.error(err)
  }
}

readJsonFile() // prints your json object
kode ifelse
sumber
6

Menggunakan paket fs-extra cukup sederhana:

Sinkronkan:

const fs = require('fs-extra')

const packageObj = fs.readJsonSync('./package.json')
console.log(packageObj.version) 

Async:

const fs = require('fs-extra')

const packageObj = await fs.readJson('./package.json')
console.log(packageObj.version) 
Arturo Menchaca
sumber
3
function parseIt(){
    return new Promise(function(res){
        try{
            var fs = require('fs');
            const dirPath = 'K:\\merge-xml-junit\\xml-results\\master.json';
            fs.readFile(dirPath,'utf8',function(err,data){
                if(err) throw err;
                res(data);
        })}
        catch(err){
            res(err);
        }
    });
}

async function test(){
    jsonData = await parseIt();
    var parsedJSON = JSON.parse(jsonData);
    var testSuite = parsedJSON['testsuites']['testsuite'];
    console.log(testSuite);
}

test();
Satyabrata Saha
sumber
0

Begitu banyak jawaban, dan tidak ada yang pernah membuat tolok ukur untuk membandingkan sinkronisasi vs async vs butuhkan. Saya menggambarkan perbedaan dalam penggunaan kasus membaca json di memori melalui keharusan, readFileSync dan readFile di sini .

Jehy
sumber
-1

Jika Anda mencari solusi lengkap untuk Asyncmemuat file JSON dari Relative Pathdengan Penanganan Kesalahan

  // Global variables
  // Request path module for relative path
    const path = require('path')
  // Request File System Module
   var fs = require('fs');


// GET request for the /list_user page.
router.get('/listUsers', function (req, res) {
   console.log("Got a GET request for list of users");

     // Create a relative path URL
    let reqPath = path.join(__dirname, '../mock/users.json');

    //Read JSON from relative path of this file
    fs.readFile(reqPath , 'utf8', function (err, data) {
        //Handle Error
       if(!err) {
         //Handle Success
          console.log("Success"+data);
         // Parse Data to JSON OR
          var jsonObj = JSON.parse(data)
         //Send back as Response
          res.end( data );
        }else {
           //Handle Error
           res.end("Error: "+err )
        }
   });
})

Struktur Direktori:

masukkan deskripsi gambar di sini

Hitesh Sahu
sumber