Используя Node.JS, как мне прочитать файл JSON в (серверную) память?


618

Фон

Я делаю некоторые эксперименты с Node.js и хотел бы прочитать объект JSON, либо из текстового файла, либо из файла .js (что лучше ??) в память, чтобы я мог быстро получить доступ к этому объекту из кода. Я понимаю, что есть такие вещи, как Монго, Альфред и т. Д., Но это не то, что мне сейчас нужно.

Вопрос

Как я могу прочитать объект JSON из текстового или js-файла и в память сервера, используя JavaScript / Node?


1
как вы называете память сервера? ваш скрипт nodejs будет работать до тех пор, пока вы заставите его работать, но вам придется где-то хранить данные, если вы не сделаете скрипт nodejs постоянным.
mpm

Ответы:


1205

Синхронизация:

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

асинхронный:

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

15
Я думаю, что JSON.parse является синхронным, прямо из v8, что означает, что даже при использовании Async люди должны быть осторожны с большими файлами JSON. так как это связало бы узел.
Sean_A91

25
Ради полноты. Их существует npm с именем jsonfile .
Стефан

5
Я не могу поверить, что было так трудно найти эту простую вещь. Каждый ответ, который я получал от google, делал HTTPRequest или JQuery, или делал это в браузере
juliangonzalez

6
два момента: (1) синхронный ответ должен быть просто let imported = require("file.json"). (2) JSON.parse должен быть асинхронным, потому что я использовал этот код для загрузки 70-мегабайтного файла JSON в память как объекта. Это занимает миллисекунды таким образом, но если я использую require(), это пыхтит .
Кайл Бейкер

8
Для людей, которые находят этот ответ в 2019 году и позже, Node.js имеет встроенную поддержку json для многих, многих версий require, причем этот ответ больше не применим, если вы просто хотите загрузить файл json. Просто пользуйтесь let data = require('./yourjsonfile.json')и уходите (с примечанием, что, если производительность require влияет на ваш код, у вас возникают проблемы, выходящие за рамки «желания загрузить файл .json»)
Майк 'Pomax' Kamermans

392

Самый простой способ, который я нашел, - это просто использовать requireпуть к файлу JSON.

Например, предположим, у вас есть следующий файл JSON.

test.json

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

Затем вы можете легко загрузить это в ваше приложение node.js, используя require

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

35
Просто, чтобы люди знали, и если я правильно помню, requireв узле работает синхронно. Погрузитесь глубоко здесь
prasanthv

@Ram Это работает для меня, может быть, ваше местоположение test.jsonбудет отличаться от его примера. Я используюnode 5.0
Гулерия

18
Другая проблема / преимущество такого метода заключается в том, что требуемые данные кэшируются, если вы не удалите специально кэшированный экземпляр
magicode118

13
«require» предназначен для загрузки модулей или конфигурационных файлов, которые вы используете, в течение всего срока службы вашего приложения. не кажется правильным использовать это для загрузки файлов.
Яки Кляйн

2
Я бы сказал, что это потенциально угроза безопасности. Если загружаемый вами json-файл содержит код JS, будет ли requireон запускать этот код? Если это так, то вам действительно нужно контролировать, откуда приходят ваши файлы json, или злоумышленник может запустить вредоносный код на вашем компьютере.
Соккёку

57

Асинхронный есть причина! Бросает камень в @mihai

Иначе, вот код, который он использовал с асинхронной версией:

// 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
согласился :), также добавил async
mihai

1
Отлично :-) Я не люблю встроенные обратные вызовы, хотя, это может привести к кошмарам обратного вызова, которых я бы предпочел избежать.
Флориан Маргэйн

9
Это там по причине .. если вы не хотите это синхронно.
Мэтт Стивенс

40

По крайней мере, в Node v8.9.1 вы можете просто сделать

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

и получить доступ ко всем элементам объекта JSON.


5
Этот подход загружает файл только один раз. Если вы измените file.jsonпосле нового требования (без перезапуска программы) данные будут с первой загрузки. У меня нет источника, чтобы поддержать это, но у меня было это в приложении, которое я строю
Lukas Ignatavičius

Ваш ответ ужасно неполный. То, что это дает вам, является объектом, и он даже не удосуживается реализовать tostring ().
Дэвид А. Грей,

3
@ DavidA.Gray Вопрос хочет иметь возможность доступа к объектам как к объектам, а не как к строкам. Помимо одиночного вопроса, Лукас упомянул, что этот ответ в порядке.
mikemaccana

2
Использование require также выполнит произвольный код в файле. Этот метод небезопасен, и я бы рекомендовал против него.
Спулсон

16

В Node 8 вы можете использовать встроенный util.promisify()модуль для асинхронного чтения файла, подобного этому

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уже асинхронный, если вы ищете версию синхронизации, его имя .readFileSync.
Атернус

Если вы хотите использовать обещания, это также относится fs/promisesк узлу 10. Примечание: API является экспериментальным: nodejs.org/api/fs.html#fs_fs_promises_api
aboutaaron

@Aternus .readFileявляется асинхронным , но не async. Это означает, что функция не определена с asyncключевым словом и не возвращает обещание, поэтому вы не можете этого сделатьawait fs.readFile('whatever.json');
Кип

@Kip как насчет CodeSandBox?
Aternus

7

использование node-fs-extra (асинхронное ожидание)

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

Использовать пакет fs-extra довольно просто:

Синхронизация:

const fs = require('fs-extra')

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

асинхронный:

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

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

Вы можете найти все случаи использования Node.js в документации по файловой системе!
надеюсь, это поможет вам!


0

Так много ответов, и никто никогда не делал эталонов для сравнения синхронизации с асинхронной и требуемой. Я описал разницу в случаях использования чтения json в памяти через require, readFileSync и readFile здесь .


-1

Если вы ищете полное решение для Asyncзагрузки файла JSON из Relative Pathс Обработка ошибок

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

Структура каталогов:

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.