Wie lese ich mit Node.JS eine JSON-Datei in den (Server-) Speicher?

618

Hintergrund

Ich experimentiere mit Node.js und möchte ein JSON-Objekt entweder aus einer Textdatei oder einer .js-Datei (was ist besser?) In den Speicher lesen, damit ich schnell über Code auf dieses Objekt zugreifen kann. Mir ist klar, dass es da draußen Dinge wie Mongo, Alfred usw. gibt, aber das ist momentan nicht das, was ich brauche.

Frage

Wie lese ich ein JSON-Objekt mit JavaScript / Node aus einer Text- oder JS-Datei in den Serverspeicher?

Matt Cashatt
quelle
1
Wie nennt man Serverspeicher? Ihr NodeJS-Skript funktioniert so lange, wie Sie es zum Laufen bringen. Sie müssen jedoch Daten irgendwo speichern, es sei denn, Sie machen das NodeJS-Skript dauerhaft.
mpm

Antworten:

1205

Synchronisieren:

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
quelle
15
Ich denke, JSON.parse ist synchron, es ist direkt von v8, was bedeutet, dass die Leute selbst mit der asynchronen Methode mit großen JSON-Dateien vorsichtig sein müssen. da würde es Knoten binden.
Sean_A91
25
Der Vollständigkeit halber. Es gibt eine npm namens jsonfile .
Stefan
5
Ich kann nicht glauben, dass es so schwierig war, diese einfache Sache zu finden. Jede Antwort, die ich von Google erhielt, war eine HTTPRequest oder JQuery zu verwenden oder es im Browser zu tun
juliangonzalez
6
zwei Punkte: (1) Die synchrone Antwort sollte einfach sein let imported = require("file.json"). (2) JSON.parse muss asynchron sein, da ich diesen Code verwendet habe, um eine 70-MB-JSON-Datei als Objekt in den Speicher zu laden. Auf diese Weise dauert es Millisekunden, aber wenn ich es benutze require(), tuckert es .
Kyle Baker
8
Für Benutzer, die diese Antwort ab 2019 finden, bietet Node.js native JSON-Unterstützung für viele, viele Versionen. requireDiese Antwort ist nicht mehr anwendbar, wenn Sie nur eine JSON-Datei laden möchten. Verwenden let data = require('./yourjsonfile.json')Sie einfach und los geht's (mit der Buchnote, dass Sie Probleme haben, wenn sich die Leistung von require auf Ihren Code auswirkt, weit über das "Laden einer .json-Datei" hinaus)
Mike 'Pomax' Kamermans
392

Der einfachste Weg, dies zu tun, besteht darin, nur requireden Pfad zu Ihrer JSON-Datei zu verwenden.

Angenommen, Sie haben die folgende JSON-Datei.

test.json

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

Sie können dies dann einfach mit in Ihre node.js-Anwendung laden require

var config = require('./test.json');
console.log(config.firstName + ' ' + config.lastName);
Travis Tidwell
quelle
35
Nur damit die Leute wissen, und wenn ich mich richtig erinnere, requireläuft der Knoten synchron. Tauchen Sie hier
Prasanthv
@Ram Es funktioniert für mich, möglicherweise ist Ihr Standort test.jsonanders als sein Beispiel. Ich benutzenode 5.0
Guleria
18
Ein weiteres Problem / Vorteil bei einer solchen Methode ist die Tatsache, dass die erforderlichen Daten zwischengespeichert werden, es sei denn, Sie löschen ausdrücklich die zwischengespeicherte Instanz
magicode118
13
"require" soll zum Laden von Modulen oder Konfigurationsdateien verwendet werden, die Sie während der gesamten Lebensdauer Ihrer Anwendung verwenden. scheint nicht richtig zu sein, um Dateien zu laden.
Yaki Klein
2
Ich würde sagen, dies ist möglicherweise eine Sicherheitsbedrohung. Wenn die von Ihnen geladene JSON-Datei JS-Code enthält, würde requiredieser Code ausgeführt? Wenn ja, müssen Sie wirklich steuern, woher Ihre JSON-Dateien stammen, oder ein Angreifer könnte schädlichen Code auf Ihrem Computer ausführen.
Sokkyoku
57

Asynchron gibt es nicht ohne Grund! Wirft Stein auf @mihai

Ansonsten ist hier der Code, den er mit der asynchronen Version verwendet hat:

// 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
quelle
9
vereinbart :), auch
asynchron
1
Großartig :-) Ich mag keine Inline-Rückrufe, aber es kann zu Rückruf-Albträumen führen, die ich lieber vermeiden möchte.
Florian Margaine
9
Es gibt es aus einem Grund ... es sei denn, Sie möchten es synchron.
Matt Stephens
40

Zumindest in Node v8.9.1 können Sie dies einfach tun

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

und greifen Sie auf alle Elemente des JSON-Objekts zu.

Alex Eftimiades
quelle
5
Dieser Ansatz lädt die Datei nur einmal. Wenn Sie die Anforderungen file.jsonnach Neuanforderung ändern (ohne das Programm neu zu starten), stammen die Daten vom ersten Laden. Ich habe keine Quelle, um dies zu unterstützen, aber ich hatte dies in der App, die ich baue
Lukas Ignatavičius
Ihre Antwort ist absolut unvollständig. Was Sie dazu bringt, ist ein Objekt, und es macht sich nicht einmal die Mühe, tostring () zu implementieren.
David A. Gray
3
@ DavidA.Gray Die Frage möchte in der Lage sein, auf die Objekte als Objekte und nicht als Zeichenfolgen zuzugreifen. Abgesehen von der Singleton-Ausgabe erwähnte Lukas, dass diese Antwort in Ordnung ist.
Mikemaccana
2
Wenn Sie require verwenden, wird auch beliebiger Code in der Datei ausgeführt. Diese Methode ist unsicher und ich würde dagegen empfehlen.
Spoulson
16

In Knoten 8 können Sie die integrierte util.promisify()Datei verwenden, um eine solche Datei asynchron zu lesen

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
quelle
3
.readFileist bereits asynchron, wenn Sie nach der Synchronisierungsversion suchen, lautet der Name .readFileSync.
Aternus
Wenn Sie Versprechen verwenden möchten, gibt es auch fs/promisesab Knoten 10. Hinweis: Die API ist experimentell: nodejs.org/api/fs.html#fs_fs_promises_api
aboutaaron
@Aternus .readFileist asynchron , aber nicht async. Das heißt, die Funktion ist weder mit einem asyncSchlüsselwort definiert , noch gibt sie ein Versprechen zurück, also können Sie es nicht tunawait fs.readFile('whatever.json');
Kip
@Kip wie wäre es mit einer CodeSandBox?
Aternus
7

mit node-fs-extra (asynchron warten)

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
ifelse.codes
quelle
6

Die Verwendung des fs-extra- Pakets ist ganz einfach:

Synchronisieren:

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
quelle
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
quelle
0

So viele Antworten, und niemand hat jemals einen Benchmark erstellt, um Synchronisierung mit Asynchronisierung und Anforderung zu vergleichen. Ich beschrieb den Unterschied in der Anwendungsfälle des Lesens json in Speicher über erfordern, readFileSync und readfile hier .

Jehy
quelle
-1

Wenn Sie nach einer Komplettlösung zum AsyncLaden einer JSON-Datei Relative Pathmit Fehlerbehandlung suchen

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

Verzeichnisaufbau:

Geben Sie hier die Bildbeschreibung ein

Hitesh Sahu
quelle