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.