Używając Node.JS, w jaki sposób odczytać plik JSON do pamięci (serwera)?


618

tło

Robię eksperymenty z Node.js i chciałbym odczytać obiekt JSON, albo z pliku tekstowego, albo z pliku .js (co jest lepsze?) Do pamięci, aby szybko uzyskać dostęp do tego obiektu z kodu. Zdaję sobie sprawę, że istnieją takie rzeczy jak Mongo, Alfred itp., Ale nie jest to teraz potrzebne.

Pytanie

Jak odczytać obiekt JSON z pliku tekstowego lub pliku js i do pamięci serwera za pomocą JavaScript / Node?


1
jak nazywacie pamięć serwera? twój skrypt nodejs będzie działał, dopóki go uruchomisz, ale będziesz musiał gdzieś przechowywać dane, chyba że uczynisz go trwałym.
mpm

Odpowiedzi:


1205

Synchronizacja:

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

Asynchronizacja:

var fs = require('fs');
var obj;
fs.readFile('file', 'utf8', function (err, data) {
  if (err) throw err;
  obj = JSON.parse(data);
});

15
Myślę, że JSON.parse jest synchroniczny, bezpośrednio z wersji 8, co oznacza, że ​​nawet przy użyciu metody Async ludzie muszą uważać na duże pliki JSON. ponieważ wiązałoby to węzeł.
Sean_A91

25
Dla kompletności. Ich istnieje npm o nazwie jsonfile .
Stefan

5
Nie mogę uwierzyć, że tak trudno było znaleźć tę prostą rzecz. Każda odpowiedź, którą otrzymałem od Google,
zawierała żądanie HTTP,

6
dwa punkty: (1) Odpowiedź synchroniczna powinna po prostu być let imported = require("file.json"). (2) JSON.parse musi być asynchroniczny, ponieważ użyłem tego kodu do załadowania pliku JSON 70mb do pamięci jako obiektu. W ten sposób zabiera to milisekundy, ale jeśli require()go użyję , to będzie się dłubał .
Kyle Baker

8
Dla osób, które znajdą tę odpowiedź w 2019 r. I później, Node.js ma natywną obsługę JSON dla wielu, wielu wersji require, z tą odpowiedzią nie ma już zastosowania, jeśli chcesz tylko załadować plik JSON. Po prostu używaj let data = require('./yourjsonfile.json')i gotowe (z przypisem, że jeśli wydajność wymaga wpływa na kod, masz problemy znacznie wykraczające poza „chęć załadowania pliku .json”)
Mike 'Pomax' Kamermans

392

Najłatwiejszym sposobem, jaki to zrobiłem, jest po prostu użycie requirei ścieżka do pliku JSON.

Załóżmy na przykład, że masz następujący plik JSON.

test.json

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

Następnie możesz łatwo załadować to do aplikacji node.js za pomocą require

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

35
Tak, żeby ludzie wiedzieli i jeśli dobrze pamiętam, requirew węźle działa synchronicznie. Nurkowania w głębokim tutaj
prasanthv

@Ram Działa dla mnie, być może Twoja lokalizacja test.jsonbędzie inna niż jego przykład. Używamnode 5.0
guleria

18
Innym problemem / korzyścią
związaną

13
„Wymagaj” służy do ładowania modułów lub pliku konfiguracyjnego, którego używasz przez cały okres użytkowania aplikacji. wydaje się niewłaściwe używanie tego do ładowania plików.
Yaki Klein

2
Powiedziałbym, że jest to potencjalnie zagrożenie bezpieczeństwa. Jeśli ładowany plik json zawiera kod JS, czy requireuruchomiłby ten kod? Jeśli tak, to naprawdę musisz kontrolować, skąd pochodzą pliki json, w przeciwnym razie osoba atakująca może uruchomić złośliwy kod na komputerze.
sokkyoku,

57

Asynchroniczny jest z jakiegoś powodu! Rzuca kamień w @mihai

W przeciwnym razie oto kod, którego używał w wersji asynchronicznej:

// 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
zgodził się :), dodał również asynchronię
mihai,

1
Świetnie :-) Nie lubię jednak wbudowanych wywołań zwrotnych, może to prowadzić do koszmarów wywołania zwrotnego, których wolałbym uniknąć.
Florian Margaine

9
Jest tam z jakiegoś powodu ... chyba że chcesz synchronicznie.
Matt Stephens

40

Przynajmniej w Node v9.9.1 możesz to zrobić

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

i uzyskaj dostęp do wszystkich elementów obiektu JSON.


5
To podejście ładuje plik tylko raz. Jeśli zmienisz file.jsonpo nowym wymaganiu (bez ponownego uruchamiania programu), dane będą od pierwszego ładowania. Nie mam źródła, aby to poprzeć, ale miałem to w aplikacji, którą
buduję

Twoja odpowiedź jest żałośnie niepełna. To, co cię dostaje, to obiekt i nawet nie przeszkadza mu to w implementacji tostring ().
David A. Gray,

3
@ DavidA.Gray Pytanie chce mieć dostęp do obiektów jako obiektów, a nie ciągów. Oprócz pojedynczego wydania Lukas wspomniał, że odpowiedź jest w porządku.
mikemaccana

2
Użycie wymagania spowoduje również wykonanie dowolnego kodu w pliku. Ta metoda jest niepewna i odradzam jej stosowanie.
spoulson

16

W węźle 8 możesz użyć wbudowanego, util.promisify()aby asynchronicznie odczytać taki plik

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
.readFilejest już asynchroniczny, jeśli szukasz wersji synchronizacji, jej nazwa to .readFileSync.
Aternus

Jeśli chcesz korzystać z obietnic, istnieje również fs/promisesod Węzła 10. Uwaga: interfejs API jest eksperymentalny: nodejs.org/api/fs.html#fs_fs_promises_api
aboutaaron

@Aternus .readFilejest asynchroniczny , ale nie async. Oznacza to, że funkcja nie jest zdefiniowana asyncsłowem kluczowym, ani nie zwraca obietnicy, więc nie możesz tego zrobićawait fs.readFile('whatever.json');
Kip

@Kip co powiesz na CodeSandBox?
Aternus,

7

using node-fs-extra (async oczekuje)

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

Korzystanie z pakietu fs-extra jest dość proste:

Synchronizacja:

const fs = require('fs-extra')

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

Asynchronizacja:

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

Tak wiele odpowiedzi i nikt nigdy nie przeprowadził testu porównawczego synchronizacji z asynchronizacją z wymaganiem. Opisałem różnicę w przypadkach korzystania z czytania json w pamięci poprzez wymagać, readFileSync i readfile tutaj .


-1

Jeśli szukasz kompletnego rozwiązania do Asyncładowania pliku JSON Relative Pathz obsługą błędów

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

Struktura katalogów:

wprowadź opis zdjęcia tutaj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.