Як за допомогою 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 повинен бути асинхронним, тому що я використовував цей код для завантаження в пам'ять файлу JSON 70 Мб як об'єкт. Це займає мілісекунди таким чином, але якщо я використовую require(), він забиває .
Кайл Бейкер

8
Для людей, які знайшли цю відповідь у 2019 році та далі, Node.js мав підтримку json для багатьох, багатьох версій require, і ця відповідь більше не застосовується, якщо ви просто хочете завантажити файл json. Просто використовуйте let data = require('./yourjsonfile.json')та вимкніть (з випискою, що якщо виконання вимоги впливає на ваш код, у вас є проблеми, що перевищують "бажаючи завантажити файл .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у вузлі працює синхронно.
Зануритися

@Ram Це працює для мене, можливо, ваше місцезнаходження test.jsonбуде відрізнятися від його прикладу. Я використовуюnode 5.0
guleria

18
Іншим питанням / перевагою такого методу є той факт, що потрібні дані кешуються, якщо ви спеціально не видалите кешований екземпляр
magicode118

13
"вимагати" призначений для використання для завантаження модулів або конфігураційного файлу, який ви використовуєте, протягом усієї тривалості роботи вашої програми. не здається правильним використовувати це для завантаження файлів.
Які Кляйн

2
Я б сказав, що це потенційно загроза безпеці. Якщо файл json, який ви завантажуєте, містить код JS, чи використовував би requireвін цей код? Якщо так, то вам дійсно потрібно контролювати, звідки беруться ваші файли json, або зловмисник може запустити шкідливий код на вашій машині.
sokkyoku

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після нової потреби (без перезавантаження програми), дані будуть з першого завантаження. У мене немає джерела, який би це підтверджував, але у мене це було в додатку, який я будую
Лукас Ігнатавічус

Ваша відповідь жахливо неповна. Те, що ви отримуєте, - це об'єкт, і це навіть не турбується впроваджувати tostring ().
Девід А. Грей

3
@ DavidA.Gray Питання хоче мати доступ до об'єктів як об’єкти, а не як рядки. Крім одинакового питання, Лукаш зазначив, що ця відповідь чудова.
mikemaccana

2
Використання вимагає також виконувати довільний код у файлі. Цей метод небезпечний, і я б рекомендував його проти.
Спулсон

16

У Вузлі 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.
Aternus

Якщо ви хочете скористатися обіцянками, є також fs/promisesпункт Node 10. Примітка: API експериментальний: nodejs.org/api/fs.html#fs_fs_promises_api
aboutaaron

@Aternus .readFileє асинхронним , але не async. Значення, функція не визначена за asyncключовим словом, а також не повертає Обіцянку, тому ви не можете цього зробитиawait fs.readFile('whatever.json');
Kip

@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 в пам'яті через вимагати, 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.