Один из лучших способов обмена информацией между приложениями, написанными на разных языках, - это использование формата JSON (JavaScript Object Notation). Благодаря единообразию и простоте JSON почти полностью заменил XML в качестве стандартного формата обмена данными в программном обеспечении, особенно в веб-сервисах.
Учитывая широкое использование JSON в программных приложениях, и особенно в приложениях на основе JavaScript, важно знать, как читать и записывать данные JSON в файл в Node.js. В этой статье мы объясним, как выполнять эти функции.
Чтение файла JSON
Давайте сначала посмотрим, как мы можем прочитать уже созданный файл. Но прежде чем мы это сделаем, нам нужно создать файл. Откройте новое окно в вашем любимом текстовом редакторе и добавьте в него следующий текст:
{
"name": "Sara",
"age": 23,
"gender": "Female",
"department": "History",
"car": "Honda"
}
Теперь сохраните этот файл как «student.json» в каталоге вашего проекта.
Чтобы прочитать данные JSON из файла, мы можем использовать модуль
Node.js fs. В этом модуле доступны две
функции, которые мы можем использовать для чтения файлов из файловой
системы: readFile
и readFileSync
.
Хотя обе эти функции выполняют схожие задачи, например, читают файлы с диска, разница заключается в том, как эти функции выполняются на самом деле, что мы объясним более подробно в следующих разделах.
Использование fs.readFileSync
Функция readFileSync
считывает данные из файла. Эта функция блокирует
выполнение остальной части кода до тех пор, пока все данные не будут
прочитаны из файла. Эта функция особенно полезна, когда вашему
приложению необходимо загрузить параметры конфигурации, прежде чем оно
сможет выполнять какие-либо другие задачи.
Чтобы продолжить наш пример, давайте воспользуемся этой функцией для
чтения файла "student.json", который мы создали ранее, с
readFileSync
функции readFileSync. Добавьте следующий код в файл .js:
'use strict';
const fs = require('fs');
let rawdata = fs.readFileSync('student.json');
let student = JSON.parse(rawdata);
console.log(student);
В приведенном выше коде Node.js мы сначала загружаем fs
в наше
приложение. Затем мы используем readFileSync
и передаем ей
относительный путь к файлу, который мы хотим прочитать. Если напечатать
объект rawdata
на консоль, вы увидите исходные данные (в
буфере ) на экране консоли:
<Buffer 7b 20 0a 20 20 20 20 22 6e 61 6d 65 22 3a 20 22 53 61 72 61 22 2c 0a 20 20 20 20 22 61 67 65 22 3a 20 32 33 2c 0a 20 20 20 20 22 67 65 6e 64 65 72 22 ... >
Однако мы хотим читать файл в его формате JSON, а не необработанные
шестнадцатеричные данные. Здесь в JSON.parse
вступает функция
JSON.parse. Эта функция обрабатывает синтаксический анализ
необработанных данных, преобразует их в текст ASCII и анализирует
фактические данные JSON в объект JavaScript. Теперь, если вы
распечатаете student
на консоли, вы получите следующий вывод:
{ name: 'Sara',
age: 23,
gender: 'Female',
department: 'History',
car: 'Honda' }
Как видите, JSON из нашего файла был успешно загружен в объект student
Использование fs.readFile
Другой способ чтения файла JSON в Node.js - использование функции
readFile
В отличие от функции readFileSync
readFile
считывает
данные файла асинхронно. Когда readFile
функция readFile, начинается
процесс чтения файла, и сразу же управление переходит к следующей
строке, выполняющей оставшиеся строки кода. После загрузки данных файла
эта функция вызовет предоставленную ей функцию обратного вызова. Таким
образом, вы не блокируете выполнение кода, ожидая, пока операционная
система вернется к вам с данными.
В нашем примере readFile
принимает два параметра: путь к файлу,
который должен быть прочитан, и функцию обратного вызова, которая должна
быть вызвана, когда файл будет полностью прочитан. При желании вы также
можете включить параметр с параметрами, но мы не будем рассматривать их
в этой статье.
Взгляните на следующий пример, чтобы понять, как использовать функцию
readFile
'use strict';
const fs = require('fs');
fs.readFile('student.json', (err, data) => {
if (err) throw err;
let student = JSON.parse(data);
console.log(student);
});
console.log('This is after the read call');
Приведенный выше код делает то же самое, что и наш предыдущий фрагмент
кода (с дополнительным console.log
), но делает это асинхронно. Вот
несколько отличий, которые вы, возможно, заметили:
(err, data) => {}
: это наша функция обратного вызова, которая выполняется после полного чтения файла.err
: Так как мы не можем легко использовать попробовать / поймать с асинхронным кодом, функция вместо дает намerr
объект , если что - то пойдет не так.null
если ошибок не было
Вы также могли заметить, что мы readFile
строку в консоль сразу после
вызова readFile. Это сделано для того, чтобы показать вам поведение
асинхронного кода. Когда приведенный выше сценарий будет выполнен, вы
увидите, что этот console.log
выполняется до выполнения readFile
обратного вызова readFile. Это связано с тем, что readFile
не
блокирует выполнение кода при чтении данных из файловой системы.
Вывод кода будет выглядеть так:
This is after the read call
{ name: 'Sara',
age: 23,
gender: 'Female',
department: 'History',
car: 'Honda' }
Как видите, последняя строка кода в нашем файле на самом деле является той, которая появляется первой в выводе.
Использование require
Другой подход - использовать глобальный require
для чтения и анализа
файлов JSON. Это тот же метод, который вы используете для загрузки
модулей Node, но его также можно использовать для загрузки JSON.
Взгляните на следующий пример.
'use strict';
let jsonData = require('./student.json');
console.log(jsonData);
Он работает точно так же, как readFileSync
мы показали выше, но это
глобально доступный метод, который вы можете использовать где угодно,
что имеет свои преимущества.
Однако у функции require
есть несколько недостатков:
- Require - это синхронная функция, которая вызывается только один раз, что означает, что вызовы получают кешированный результат. Если файл обновлен, вы не можете перечитать его с помощью этого метода.
- Ваш файл должен иметь расширение .json, поэтому он не может быть
таким гибким. Без правильного расширения
require
не обрабатывает файл как файл JSON.
Запись JSON в файл
Подобно readFile
и readFileSync
, есть две функции для записи
данных в файлы : writeFile
и
writeFileSync
. Как следует из названий, writeFile
записывает данные
в файл асинхронным способом, в то время writeFileSync
функция
writeFileSync записывает данные в файл синхронным образом.
Мы рассмотрим подробнее в следующих разделах.
Использование fs.writeFileSync
Функция writeFileSync
принимает 2-3 параметра: путь к файлу для записи
данных, данные для записи и необязательный параметр.
Обратите внимание: если файл еще не существует, для вас создается новый файл. Взгляните на следующий пример:
'use strict';
const fs = require('fs');
let student = {
name: 'Mike',
age: 23,
gender: 'Male',
department: 'English',
car: 'Honda'
};
let data = JSON.stringify(student);
fs.writeFileSync('student-2.json', data);
В приведенном выше примере мы сохраняем наш объект JSON student
в файл
с именем «student-2.json». Обратите внимание, что здесь мы должны
использовать JSON.stringify
перед сохранением данных. Точно так же,
как нам нужно было проанализировать данные в формате JSON, когда мы
читаем файл JSON, нам нужно «преобразовать» данные в строку, прежде чем
мы сможем сохранить их в строковой форме в файле.
Выполните приведенный выше код и откройте файл student-2.json. Вы должны увидеть в файле следующее содержимое:
{"name":"Mike","age":23,"gender":"Male","department":"English","car":"Honda"}
Хотя это данные, которые мы хотели записать, они представлены в виде
одной строковой строки, которую нам трудно прочитать. Если вы хотите,
чтобы сериализованный JSON был удобочитаемым человеком, измените
JSON.Stringify
следующим образом:
let data = JSON.stringify(student, null, 2);
Здесь мы говорим методу добавить новые строки и пару отступов в сериализованный JSON. Теперь, если вы откроете файл "student-2.json", вы должны увидеть текст в следующем формате.
{
"name": "Mike",
"age": 23,
"gender": "Male",
"department": "English",
"car": "Honda"
}
Использование fs.writeFile
Как я уже говорил ранее, writeFile
функция выполняется в асинхронном
режиме, что означает наш код не блокируется , а данные записываются в
файл. И, как и в случае с асинхронными методами ранее, нам нужно
передать обратный вызов этой функции.
Давайте напишем еще один файл, student-3.json, с writeFile
функции
writeFile.
'use strict';
const fs = require('fs');
let student = {
name: 'Mike',
age: 23,
gender: 'Male',
department: 'English',
car: 'Honda'
};
let data = JSON.stringify(student, null, 2);
fs.writeFile('student-3.json', data, (err) => {
if (err) throw err;
console.log('Data written to file');
});
console.log('This is after the write call');
Результатом вышеупомянутого скрипта будет:
This is after the write call
Data written to file
И снова вы можете видеть, что последняя строка нашего кода фактически отображается первой в консоли, поскольку наш обратный вызов еще не был вызван. Это приводит к значительной экономии времени выполнения, если у вас есть большие объемы данных для записи в файл или если у вас довольно много файлов для записи.
Учить больше
Хотите узнать больше об основах Node.js? Лично я бы порекомендовал пройти онлайн-курс, например Learn Node.js от Веса Боса{.bos-link} . Вы не только изучите самый современный синтаксис ES2017, но и сможете создать полноценное ресторанное приложение. По моему опыту, создание подобных реальных приложений - самый быстрый способ учиться.
Заключение
В этой статье мы показали, как вы можете читать и записывать данные JSON из файлов и в файлы, что является очень распространенной и важной задачей, которую нужно знать, как веб-программист.
fs
есть несколько методов как для чтения, так и для записи в файлы
JSON. Функции readFile
и readFileSync
будут читать данные JSON из
файла асинхронно и синхронно соответственно. Вы также можете
использовать глобальный require
для обработки чтения / анализа данных
JSON из файла в одной строке кода. Однако require
является синхронным
и может читать данные JSON только из файлов с расширением .json.
Точно так же функции writeFile
и writeFileSync
из fs
записывают
данные JSON в файл асинхронным и синхронным образом соответственно.