À l'aide de Node.JS, comment lire un fichier JSON dans la mémoire (du serveur)?

618

Contexte

Je fais une expérimentation avec Node.js et je voudrais lire un objet JSON, soit à partir d'un fichier texte ou d'un fichier .js (ce qui est mieux ??) en mémoire afin que je puisse accéder rapidement à cet objet à partir du code. Je me rends compte qu'il y a des choses comme Mongo, Alfred, etc., mais ce n'est pas ce dont j'ai besoin en ce moment.

Question

Comment lire un objet JSON dans un fichier texte ou js et dans la mémoire du serveur à l'aide de JavaScript / Node?

Matt Cashatt
la source
1
comment appelez-vous la mémoire du serveur? votre script nodejs fonctionnera aussi longtemps que vous le ferez fonctionner, mais vous devrez stocker des données quelque part à moins que vous ne rendiez le script nodejs persistant.
mpm

Réponses:

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);
});
mihai
la source
15
Je pense que JSON.parse est synchrone, c'est directement à partir de la v8, ce qui signifie que même avec la méthode Async, les gens doivent faire attention aux gros fichiers JSON. car il attacherait le nœud.
Sean_A91
25
Par souci d'exhaustivité. Leur existe un npm appelé jsonfile .
Stefan
5
Je ne peux pas croire qu'il était si difficile de trouver cette chose simple. Chaque réponse que j'ai obtenue de Google faisait une requête HTTP ou utilisait JQuery ou le faisait dans le navigateur
juliangonzalez
6
deux points: (1) La réponse synchrone devrait être juste let imported = require("file.json"). (2) JSON.parse doit être asynchrone, car j'ai utilisé ce code pour charger un fichier JSON de 70 Mo en mémoire en tant qu'objet. Cela prend des millisecondes de cette façon, mais si j'utilise require(), il s'étouffe .
Kyle Baker le
8
Pour les personnes trouvant cette réponse en 2019 et après, Node.js a pris en charge natif json pour de nombreuses versions require, cette réponse n'est plus applicable si vous souhaitez simplement charger un fichier json. Il suffit d'utiliser let data = require('./yourjsonfile.json')et de partir (avec la note que si les performances de require ont un impact sur votre code, vous avez des problèmes bien au-delà de "vouloir charger un fichier .json")
Mike 'Pomax' Kamermans
392

La façon la plus simple que j'ai trouvée de le faire est d'utiliser simplement requireet le chemin d'accès à votre fichier JSON.

Par exemple, supposons que vous ayez le fichier JSON suivant.

test.json

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

Vous pouvez ensuite facilement le charger dans votre application node.js en utilisant require

var config = require('./test.json');
console.log(config.firstName + ' ' + config.lastName);
Travis Tidwell
la source
35
Juste pour que les gens le sachent, et si je me souviens bien, le requirenœud fonctionne de manière synchrone. Plongez au plus profond ici
prasanthv
@Ram Cela fonctionne pour moi, votre emplacement test.jsonpourrait être différent de son exemple. J'utilisenode 5.0
Guleria
18
Un autre problème / avantage avec une telle méthode est le fait que les données requises sont mises en cache sauf si vous supprimez spécifiquement l'instance mise en cache
magicode118
13
"require" est destiné à être utilisé pour charger des modules ou un fichier de configuration que vous utilisez pendant toute la durée de vie de votre application. ne semble pas approprié de l'utiliser pour charger des fichiers.
Yaki Klein
2
Je dirais que c'est potentiellement une menace pour la sécurité. Si le fichier json que vous chargez contient du code JS, est- requirece qu'il exécuterait ce code? Si c'est le cas, vous devez vraiment contrôler la provenance de vos fichiers json ou un attaquant pourrait exécuter du code malveillant sur votre machine.
sokkyoku
57

Asynchrone est là pour une raison! Jette la pierre à @mihai

Sinon, voici le code qu'il a utilisé avec la version asynchrone:

// 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
la source
9
d'accord :), a également ajouté async
mihai
1
Génial :-) Je n'aime pas les rappels en ligne cependant, cela peut conduire à des cauchemars de rappel que je préfère éviter.
Florian Margaine
9
Il est là pour une raison ... à moins que vous ne le vouliez de manière synchrone.
Matt Stephens
40

Au moins dans Node v8.9.1, vous pouvez simplement faire

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

et accéder à tous les éléments de l'objet JSON.

Alex Eftimiades
la source
5
Cette approche ne charge le fichier qu'une seule fois. Si vous modifiez la file.jsonnouvelle exigence (sans redémarrer le programme), les données proviendront du premier chargement. Je n'ai pas de source pour soutenir cela, mais je l'ai eu dans l'application que je construis
Lukas Ignatavičius
Votre réponse est malheureusement incomplète. Ce que vous obtenez est un objet, et cela ne prend même pas la peine d'implémenter tostring ().
David A. Gray
3
@ DavidA.Gray La question veut pouvoir accéder aux objets comme des objets, pas comme des chaînes. Mis à part le problème de singleton, Lukas a mentionné que cette réponse était correcte.
mikemaccana
2
L'utilisation de require exécutera également du code arbitraire dans le fichier. Cette méthode n'est pas sûre et je le déconseille.
spoulson
16

Dans Node 8, vous pouvez utiliser le intégré util.promisify()pour lire de manière asynchrone un fichier comme celui-ci

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
la source
3
.readFileest déjà asynchrone, si vous recherchez la version de synchronisation, son nom est .readFileSync.
Aternus
Si vous voulez utiliser des promesses, il y en a aussi à fs/promisespartir du nœud 10. Remarque: l'API est expérimentale: nodejs.org/api/fs.html#fs_fs_promises_api
aboutaaron
@Aternus .readFileest asynchrone , mais pas async. Cela signifie que la fonction n'est pas définie avec un asyncmot-clé, ni ne renvoie une promesse, donc vous ne pouvez pas le faireawait fs.readFile('whatever.json');
Kip
@Kip que diriez-vous d'un CodeSandBox?
Aternus
7

en utilisant node-fs-extra (async wait)

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
la source
6

L'utilisation du package fs-extra est assez simple:

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) 
Arturo Menchaca
la source
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
la source
2

https://nodejs.org/dist/latest-v6.x/docs/api/fs.html#fs_fs_readfile_file_options_callback

var fs = require('fs');  

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

// options
fs.readFile('/etc/passwd', 'utf8', callback);

https://nodejs.org/dist/latest-v6.x/docs/api/fs.html#fs_fs_readfilesync_file_options

Vous pouvez trouver toutes les utilisations de Node.js dans la documentation du système de fichiers!
j'espère que cette aide pour vous!

xgqfrms
la source
0

Autant de réponses, et personne n'a jamais fait de référence pour comparer sync vs async vs require. J'ai décrit la différence dans les cas d'utilisation de la lecture de json en mémoire via require, readFileSync et readFile ici .

Jehy
la source
-1

Si vous cherchez une solution complète pour Asynccharger un fichier JSON Relative Pathavec la gestion des erreurs

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

Structure du répertoire:

entrez la description de l'image ici

Hitesh Sahu
la source