Utilizzando Node.JS, come posso leggere un file JSON nella memoria (server)?


618

sfondo

Sto facendo un po 'di sperimentazione con Node.js e vorrei leggere un oggetto JSON, da un file di testo o un file .js (che è meglio ??) in memoria in modo da poter accedere rapidamente a quell'oggetto dal codice. Mi rendo conto che ci sono cose come Mongo, Alfred, ecc. Là fuori, ma non è quello di cui ho bisogno in questo momento.

Domanda

Come posso leggere un oggetto JSON da un file di testo o js e nella memoria del server usando JavaScript / Node?


1
come si chiama la memoria del server? lo script nodejs funzionerà fintanto che lo fai funzionare, ma dovrai archiviare i dati da qualche parte a meno che non rendi lo script nodejs persistente.
mpm,

Risposte:


1205

Sync:

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);
});

15
Penso che JSON.parse sia sincrono, è direttamente dalla v8, il che significa che anche con il modo Asincrono, le persone devono fare attenzione con i file JSON di grandi dimensioni. poiché avrebbe legato il nodo.
Sean_A91,

25
Per amor di completezza. Il loro esiste un npm chiamato jsonfile .
Stefan,

5
Non posso credere che sia stato così difficile trovare questa cosa semplice. Ogni risposta che ho ricevuto da Google stava facendo un HTTPRequest o usando JQuery o facendolo nel browser
juliangonzalez

6
due punti: (1) La risposta sincrona dovrebbe essere solo let imported = require("file.json"). (2) JSON.parse deve essere asincrono, perché ho usato questo codice per caricare un file JSON da 70 MB in memoria come oggetto. Ci vogliono millisecondi in questo modo, ma se lo uso require(), soffoca .
Kyle Baker,

8
Per le persone che hanno trovato questa risposta nel 2019 e in seguito, Node.js ha avuto il supporto nativo json per molte, molte versioni require, con questa risposta non più applicabile se si desidera solo caricare un file json. Basta usare let data = require('./yourjsonfile.json')e il gioco è fatto (con il booknote che se l'esecuzione del requisito influisce sul codice, si hanno problemi ben al di là di "voler caricare un file .json")
Mike 'Pomax' Kamermans

392

Il modo più semplice che ho trovato per fare questo è semplicemente usare requiree il percorso del tuo file JSON.

Ad esempio, supponiamo di avere il seguente file JSON.

test.json

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

È quindi possibile caricarlo facilmente nell'applicazione node.js utilizzando require

var config = require('./test.json');
console.log(config.firstName + ' ' + config.lastName);

35
Proprio così la gente lo sa, e se ricordo bene, requirenel nodo si esegue in modo sincrono. Tuffati nel profondo qui
prasanthv,

@Ram Funziona per me potrebbe essere la tua posizione test.jsonsarebbe diversa dal suo esempio. Sto usandonode 5.0
guleria il

18
Un altro problema / vantaggio con tale metodo è il fatto che i dati richiesti vengono memorizzati nella cache a meno che non si elimini specificamente l'istanza memorizzata nella cache
magicode118

13
"Require" è pensato per essere utilizzato per caricare moduli o file di configurazione che stai utilizzando per tutta la durata della tua applicazione. non sembra giusto usarlo per caricare i file.
Yaki Klein,

2
Direi che questa è potenzialmente una minaccia alla sicurezza. Se il file json che stai caricando contiene il codice JS, requirelo eseguirà quel codice? In tal caso, devi davvero controllare da dove provengono i tuoi file json o un utente malintenzionato potrebbe eseguire codice dannoso sul tuo computer.
sokkyoku,

57

Asincrono è lì per un motivo! Lancia la pietra a @mihai

Altrimenti, ecco il codice che ha usato con la versione asincrona:

// 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
}

9
d'accordo :), aggiunto anche asincrono
mihai

1
Fantastico :-) Non mi piacciono i callback in linea, può portare a incubi di callback che preferirei evitare.
Florian Margaine,

9
È lì per un motivo ... a meno che tu non lo desideri in modo sincrono.
Matt Stephens,

40

Almeno in Nodo v8.9.1, puoi semplicemente farlo

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

e accedi a tutti gli elementi dell'oggetto JSON.


5
Questo approccio carica il file una sola volta. Se si modificano i dati file.jsondopo la nuova richiesta (senza riavviare il programma) i dati verranno dal primo caricamento. Non ho la fonte per
appoggiarlo

La tua risposta è terribilmente incompleta. Quello che ti prende è un oggetto e non si preoccupa nemmeno di implementare tostring ().
David A. Gray,

3
@ DavidA.Gray La domanda vuole poter accedere agli oggetti come oggetti, non come stringhe. A parte il problema del singleton, Lukas ha menzionato questa risposta va bene.
mikemaccana,

2
L'uso di request eseguirà anche il codice arbitrario nel file. Questo metodo non è sicuro e lo sconsiglio.
spoulson,

16

Nel nodo 8 è possibile utilizzare il built-in util.promisify()per leggere in modo asincrono un file come questo

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
  })

3
.readFileè già asincrono, se stai cercando la versione di sincronizzazione, il suo nome è .readFileSync.
Aternus,

Se vuoi usare le promesse, c'è anche fs/promisesdal Nodo 10. Nota: l'API è sperimentale: nodejs.org/api/fs.html#fs_fs_promises_api
aboutaaron

@Aternus .readFileè asincrono , ma non async. Significato, la funzione non è definita con la asyncparola chiave, né restituisce una Promessa, quindi non puoi farloawait fs.readFile('whatever.json');
Kip

@Kip che ne dici di un CodeSandBox?
Aternus,

7

usando node-fs-extra (async waitit)

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

6

L'uso del pacchetto fs-extra è abbastanza semplice:

Sync:

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) 

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();


0

Così tante risposte, e nessuno ha mai fatto un benchmark per confrontare sincronizzazione vs asincrono vs richiesta. Ho descritto la differenza nei casi d'uso di lettura di json in memoria tramite request, readFileSync e readFile qui .


-1

Se stai cercando una soluzione completa per il Asynccaricamento di un file JSON da Relative Pathcon Gestione errori

  // 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 )
        }
   });
})

Struttura delle directory:

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.