Node js прочитать файл json
Для работы с файлами в Node.js используется встроенный модуль fs , который выполняет все синхронные и асинхронные операции ввода/вывода применительно к файлам. Чтение и запись файла могут осуществляться одним из двумя способов:
- с использованием Buffer ;
- через создание соответствующего потока.
Чтение файлов и директорий¶
Для чтения файла в асинхронном режиме используется метод Node.js readFile() , который принимает три параметра:
- путь к файлу;
- кодировка;
- callback-функция, вызываемая после получения содержимого файла.
Callback-функции передается два аргумента: ошибка и полученные данные в строковом формате. Если операция прошла успешна, то в качестве ошибки передается null .
Если в readFile() не указать кодировку, то данные файла будут возвращены в формате Buffer .
Поскольку метод выполняется асинхронно, то не происходит блокировки главного процесса Node.js. Но в некоторых случаях может понадобиться синхронное чтение файла, для этого есть метод readFileSync() , но при этом выполнение главного процесса будет заблокировано до тех пор, пока полностью не будет загружено содержимое файла.
Node.js readFileSync() возвращает результат чтения файла и принимает два параметра:
Обработка и перехват ошибок при использовании readFileSync() осуществляется с помощью конструкции try<. >catch() <. >.
Чтобы инициировать ошибку, укажите неправильный путь к файлу.
Методы readFile() и readFileSync() для работы с файлами используют Buffer . Но есть и другой способ считать содержимое файла: создать поток с помощью Node.js fs.createReadStream() . Любой поток в Node.js является экземпляром класса EventEmitter , который позволяет обрабатывать возникающие в потоке события.
Параметры, принимаемые fs.createReadStream() :
- путь к файлу;
- объект со следующими настройками:
- encoding - кодировка (по умолчанию utf8 );
- mode - режим доступа (по умолчанию 0o666 );
- autoClose - если true , то при событиях error и finish поток закроется автоматически (по умолчанию true ).
Вместо объекта настроек можно передать строку, которая будет задавать кодировку.
Использование потока имеет ряд преимуществ перед Buffer :
Для чтения директорий используются методы readdir() и readdirSync() , для асинхронного и синхронного режимов соответственно.
Node.js readdir() работает асинхронно и принимает три аргумента:
- путь к директории;
- кодировку;
- callback-функцию, которая принимает аргументами ошибку и массив файлов директории (при успешном выполнении операции ошибка передается как null ).
Node.js readdirSync() работает синхронно, возвращает массив найденных файлов и принимает два параметра:
Создание и запись файлов и директорий¶
В Node.js файлы могут быть записаны также синхронно и асинхронно. Для асинхронной записи имеется метод writeFile() , принимающий следующие аргументы:
- путь к файлу;
- данные для записи;
- параметры записи:
- кодировка (по умолчанию utf8 );
- права доступа (по умолчанию 0o666 );
- callback-функция, которая вызывается по завершению операции и единственным аргументом принимает ошибку (в случае успешной записи передается null ).
Если нет необходимости указывать параметры записи, то третьим параметром Node.js writeFile() можно сразу передать callback-функцию.
Для синхронной записи Node.js файла используйте writeFileSync() . Метод принимает все те же аргументы, что и writeFile() за исключением callback-функции. В качестве значения возвращает undefined .
Как и в случае с readFileSync() обработка ошибок происходит с помощью try<. >catch() <. >.
Методы writeFile() и writeFileSync() перезаписывают уже имеющуюся в файле информацию новыми данными. Если вам нужно внести новые данные без удаления старых, используйте методы appendFIle() и appendFileAsync() , которые имеют идентичные параметры.
Для записи файла через потока ввода имеется метод fs.createWriteStream() , который возвращает поток ввода и принимает два параметра:
- путь к файлу;
- объект со следующими настройками:
- encoding - кодировка (по умолчанию utf8 );
- mode - режим доступа (по умолчанию 0o666 );
- autoClose - если true , то при событиях error и finish поток закроется автоматически (по умолчанию true ).
Чтобы создать директорию, используйте методы mkdir() и mkdirSync() .
Node.js mkdir() работает асинхронно и принимает в качестве параметров:
- путь к директории;
- объект со следующими настройками:
- recursive - если true , создает директорию и все ее родительские директории согласно указанному пути, если они еще не существуют (по умолчанию false , т. е. все родительские директории уже должны быть созданы, иначе будет сгенерирована ошибка);
- mode - режим доступа, параметр не поддерживается на ОС Windows (по умолчанию 0o777 );
- callback-функцию, которая единственным аргументом принимает ошибку, при успешном создании директории передается null .
Вторым параметром можно сразу передать callback-функцию.
Node.js mkdirSync() создает директорию синхронно и возвращает undefined . Обработка ошибок осуществляется через try<. >catch() <. >. Метод mkdirSync() принимает те же параметры, что и mkdir() , за исключением callback-функции.
Удаление файлов и директорий¶
Чтобы удалить в Node.js файлы используйте методы unlink() и unlinkSync() .
Метод unlink() асинхронный и принимает имя файла, который нужно удалить, и callback-функцию с ошибкой в качестве параметра ( null , если удаление прошло успешно).
Для синхронного удаления файла используйте unlinkSync() , которому единственным аргументом передается имя файла.
Для удаления директорий имеются методы rmdir() и rmdirSync() соответственно. Они полностью идентичны unlink() и unlinkSync() , только вместо имени файла принимают имя директории.
у меня есть файл, который хранит много объектов JavaScript в форме JSON, и мне нужно прочитать файл, создать каждый из объектов и сделать что-то с ними (вставьте их в БД в моем случае). Объекты JavaScript могут быть представлены в виде:
Формат A:
или Формат B:
отметим, что . указывает на множество объектов JSON. Я знаю, что могу прочитать весь файл в память, а затем использовать JSON.parse() такой:
однако файл может быть очень большим, я бы предпочел использовать поток для этого. Проблема, которую я вижу с потоком, заключается в том, что содержимое файла может быть разбито на куски данных в любой момент, поэтому как я могу использовать JSON.parse() на такие объекты?
в идеале каждый объект будет считываться как отдельный кусок данных, но я не уверен в как это делается.
примечание, Я хочу предотвратить чтение всего файл в памяти. Эффективность времени для меня не имеет значения. Да, я мог бы попытаться прочитать несколько объектов сразу и вставить их все сразу, но это настройка производительности - мне нужен способ, который гарантированно не вызовет перегрузку памяти, независимо от того, сколько объектов содержится в файле.
Я могу использовать FormatA или FormatB или, может быть, что-то еще, просто укажите в своем ответе. Спасибо!
чтобы обработать файл по строкам, вам просто нужно отделить чтение файла и кода, который действует на этом входе. Вы можете сделать это, буферизуя свой ввод, пока не нажмете новую строку. Предполагая, что у нас есть один объект JSON на строку (в основном, формат B):
каждый раз, когда поток файлов получает данные из файловой системы, он хранится в буфере, а затем pump называется.
если в буфере нет новой строки, pump просто возвращается, ничего не делая. В следующий раз, когда поток получит данные, в буфер будет добавлено больше данных (и потенциально новая строка), и тогда у нас будет полный объект.
если есть новая строка, pump отрезает буфер от начала до новой строки и передает его в process . Затем он снова проверяет, есть ли еще одна новая строка в буфере ( while петли). Таким образом, мы можем обработать все строки, которые читались в текущем кусок.
наконец, process вызывается один раз в строке ввода. Если присутствует, он удаляет символ возврата каретки (чтобы избежать проблем с окончаниями строк-LF vs CRLF), а затем вызывает JSON.parse одна линия. На этом этапе вы можете делать все, что вам нужно, с вашим объектом.
отметим, что JSON.parse строго о том, что он принимает в качестве ввода; вы должны указать свои идентификаторы и строковые значения в двойные кавычки. Другими словами, бросит ошибка; вы должны использовать .
потому что не более чем набор данных будет в памяти, это будет чрезвычайно эффективной памяти. Это также будет очень быстро. Быстрый тест показал, что я обработал 10 000 строк менее чем за 15 мс.
Так же, как я думал, что было бы интересно написать потоковый парсер JSON, я также подумал, что, возможно, я должен сделать быстрый поиск, чтобы увидеть, есть ли он уже доступен.
Так как я только нашел его, я, очевидно, не использовал его, поэтому я не могу прокомментировать его качество, но мне будет интересно услышать, если это завод.
это действительно работает рассмотрим следующий CoffeeScript:
это будет регистрировать объекты по мере их поступления, если поток представляет собой массив объектов. Поэтому единственное, что буферизуется, - это один объект за раз.
чтобы продемонстрировать на рабочем примере:
данные.в JSON:
Здравствуйте.js:
Я понимаю, что вы хотите избежать чтения всего файла JSON в память, если это возможно, однако, если у вас есть доступная память, это может быть не плохая идея с точки зрения производительности. Использование node.JS require () в файле json загружает данные в память очень быстро.
Я провел два теста, чтобы увидеть, как выглядела производительность при печати атрибута из каждой функции из файла 81mb geojson.
в 1-м тесте я прочитал весь файл geojson в память, используя var data = require('./geo.json') . Это заняло 3330 миллисекунд, а затем печать атрибута из каждой функции заняла 804 миллисекунды в общей сложности 4134 миллисекунды. Однако оказалось, что узел.js использовал 411mb памяти.
во втором тесте я использовал ответ @arcseldon с jsonstream + event-stream. Я изменил запрос JSONPath, чтобы выбрать только то, что мне нужно. На этот раз память никогда не поднималась выше 82MB, однако теперь все это заняло 70 секунд!
у меня было аналогичное требование, мне нужно прочитать большой файл json в узле js и обработать данные кусками и вызвать api и сохранить в mongodb. inputFile.JSON-это как:
теперь я использовал JsonStream и EventStream для достижения этого синхронно.
Я решил эту проблему с помощью разделить модуль npm. Пустите свой поток в Сплит, и он будет"разбейте поток и соберите его так, чтобы каждая строка была куском".
Если у вас есть контроль над входным файлом, и это массив объектов, вы можете решить эту проблему более легко. Организуйте вывод файла с каждой записью в одну строку, например:
Это все еще действует JSON.
затем используйте узел.модуль JS readline для обработки их по одной строке за раз.
я написал модуль, который может это сделать, называется BFJ. В частности, метод bfj.match может использоваться для разбиения большого потока на дискретные куски JSON:
здесь bfj.match возвращает читаемый поток в объектном режиме, который будет получать проанализированные элементы данных, и передается 3 аргумента:
читаемый поток, содержащий входной JSON.
предикат, указывающий, какие элементы из проанализированных JSON будет перенесен в поток результатов.
объект options, указывающий, что вход разделен новой строкой JSON (это для обработки формата B из вопроса, это не требуется для формата A).
по вызову bfj.match сначала проанализирует JSON из глубины входного потока, вызывая предикат с каждым значением, чтобы определить, следует ли перемещать этот элемент в результирующий поток. Предикат передается тремя аргументы:
ключ свойства или индекс массива (это будет undefined для элементов верхнего уровня).
глубина элемента в структуре JSON (ноль для элементов верхнего уровня).
конечно более сложный предикат можно также использовать по мере необходимости согласно требованиям. Можно также передать строку или регулярное выражение вместо функции предиката, если вы хотите выполнить простые совпадения с ключами свойств.
Я думаю, вам нужно использовать базу данных. MongoDB-хороший выбор в этом случае, потому что он совместим с JSON.
обновление: Вы можете использовать mongoimport инструмент для импорта данных JSON в MongoDB.
Сегодня, в девятой части перевода руководства по Node.js, мы поговорим о работе с файлами. В частности, речь пойдёт о модулях fs и path — о файловых дескрипторах, о путях к файлам, о получении информации о файлах, об их чтении и записи, о работе с директориями.
Работа с файловыми дескрипторами в Node.js
Прежде чем вы сможете взаимодействовать с файлами, находящимися в файловой системе вашего сервера, вам необходимо получить дескриптор файла.
Дескриптор можно получить, воспользовавшись для открытия файла асинхронным методом open() из модуля fs :
Обратите внимание на второй параметр, r , использованный при вызове метода fs.open() . Это — флаг, который сообщает системе о том, что файл открывают для чтения. Вот ещё некоторые флаги, которые часто используются при работе с этим и некоторыми другими методами:
- r+ — открыть файл для чтения и для записи.
- w+ — открыть файл для чтения и для записи, установив указатель потока в начало файла. Если файл не существует — он создаётся.
- a — открыть файл для записи, установив указатель потока в конец файла. Если файл не существует — он создаётся.
- a+ — открыть файл для чтения и записи, установив указатель потока в конец файла. Если файл не существует — он создаётся.
После получения дескриптора любым из вышеописанных способов вы можете производить с ним необходимые операции.
Данные о файлах
С каждым файлом связан набор данных о нём, исследовать эти данные можно средствами Node.js. В частности, сделать это можно, используя метод stat() из модуля fs .
Вызывают этот метод, передавая ему путь к файлу, и, после того, как Node.js получит необходимые сведения о файле, он вызовет коллбэк, переданный методу stat() . Вот как это выглядит:
В Node.js имеется возможность синхронного получения сведений о файлах. При таком подходе главный поток блокируется до получения свойств файла:
Информация о файле попадёт в константу stats . Что это за информация? На самом деле, соответствующий объект предоставляет нам большое количество полезных свойств и методов:
- Методы .isFile() и .isDirectory() позволяют, соответственно, узнать, является ли исследуемый файл обычным файлом или директорией.
- Метод .isSymbolicLink() позволяет узнать, является ли файл символической ссылкой.
- Размер файла можно узнать, воспользовавшись свойством .size .
Пути к файлам в Node.js и модуль path
Путь к файлу — это адрес того места в файловой системе, где он расположен.
В Linux и macOS путь может выглядеть так:
В Windows пути выглядят немного иначе:
На различия в форматах записи путей при использовании разных операционных систем следует обращать внимание, учитывая операционную систему, используемую для развёртывания Node.js-сервера.
В Node.js есть стандартный модуль path , предназначенный для работы с путями к файлам. Перед использованием этого модуля в программе его надо подключить:
▍Получение информации о пути к файлу
Если у вас есть путь к файлу, то, используя возможности модуля path , вы можете, в удобном для восприятия и дальнейшей обработки виде, узнать подробности об этом пути. Выглядит это так:
Здесь, в строке notes , хранится путь к файлу. Для разбора пути использованы следующие методы модуля path :
- dirname() — возвращает родительскую директорию файла.
- basename() — возвращает имя файла.
- extname() — возвращает расширение файла.
▍Работа с путями к файлам
Несколько частей пути можно объединить, используя метод path.join() :
Найти абсолютный путь к файлу на основе относительного пути к нему можно с использованием метода path.resolve() :
В данном случае Node.js просто добавляет /flavio.txt к пути, ведущем к текущей рабочей директории. Если при вызове этого метода передать ещё один параметр, представляющий путь к папке, метод использует его в качестве базы для определения абсолютного пути:
Если путь, переданный в качестве первого параметра, начинается с косой черты — это означает, что он представляет собой абсолютный путь.
Вот ещё один полезный метод — path.normalize() . Он позволяет найти реальный путь к файлу, используя путь, в котором содержатся спецификаторы относительного пути вроде точки ( . ), двух точек ( .. ), или двух косых черт:
Методы resolve() и normalize() не проверяют существование директории. Они просто находят путь, основываясь на переданным им данным.
Чтение файлов в Node.js
Самый простой способ чтения файлов в Node.js заключается в использовании метода fs.readFile() с передачей ему пути к файлу и коллбэка, который будет вызван с передачей ему данных файла (или объекта ошибки):
Если надо, можно воспользоваться синхронной версией этого метода — fs.readFileSync() :
По умолчанию при чтении файлов используется кодировка utf8 , но кодировку можно задать и самостоятельно, передав методу соответствующий параметр.
Методы fs.readFile() и fs.readFileSync() считывают в память всё содержимое файла. Это означает, что работа с большими файлами с применением этих методов серьёзно отразится на потреблении памяти вашим приложением и окажет влияние на его производительность. Если с такими файлами нужно работать, лучше всего воспользоваться потоками.
Запись файлов в Node.js
В Node.js легче всего записывать файлы с использованием метода fs.writeFile() :
Есть и синхронная версия того же метода — fs.writeFileSync() :
Эти методы, по умолчанию, заменяют содержимое существующих файлов. Изменить их стандартное поведение можно, воспользовавшись соответствующим флагом:
Тут могут использоваться флаги, которые мы уже перечисляли в разделе, посвящённом дескрипторам. Подробности о флагах можно узнать здесь.
Присоединение данных к файлу
Метод fs.appendFile() (и его синхронную версию — fs.appendFileSync() ) удобно использовать для присоединения данных к концу файла:
Об использовании потоков
Выше мы описывали методы, которые, выполняя запись в файл, пишут в него весь объём переданных им данных, после чего, если используются их синхронные версии, возвращают управление программе, а если применяются асинхронные версии — вызывают коллбэки. Если вас такое состояние дел не устраивает — лучше будет воспользоваться потоками.
Работа с директориями в Node.js
Модуль fs предоставляет в распоряжение разработчика много удобных методов, которые можно использовать для работы с директориями.
▍Проверка существования папки
Для того чтобы проверить, существует ли директория и может ли Node.js получить к ней доступ, учитывая разрешения, можно использовать метод fs.access() .
▍Создание новой папки
Для того чтобы создавать новые папки, можно воспользоваться методами fs.mkdir() и fs.mkdirSync() :
▍Чтение содержимого папки
Для того чтобы прочесть содержимое папки, можно воспользоваться методами fs.readdir() и fs.readdirSync() . В этом примере осуществляется чтение содержимого папки — то есть — сведений о том, какие файлы и поддиректории в ней имеются, и возврат их относительных путей:
Вот так можно получить полный путь к файлу:
Результаты можно отфильтровать для того, чтобы получить только файлы и исключить из вывода директории:
▍Переименование папки
Для переименования папки можно воспользоваться методами fs.rename() и fs.renameSync() . Первый параметр — это текущий путь к папке, второй — новый:
Переименовать папку можно и с помощью синхронного метода fs.renameSync() :
▍Удаление папки
Для того чтобы удалить папку, можно воспользоваться методами fs.rmdir() или fs.rmdirSync() . Надо отметить, что удаление папки, в которой что-то есть, задача несколько более сложная, чем удаление пустой папки. Если вам нужно удалять такие папки, воспользуйтесь пакетом fs-extra, который весьма популярен и хорошо поддерживается. Он представляет собой замену модуля fs , расширяющую его возможности.
Метод remove() из пакета fs-extra умеет удалять папки, в которых уже что-то есть.
Установить этот модуль можно так:
Вот пример его использования:
Его методами можно пользоваться в виде промисов:
Допустимо и применение конструкции async/await:
Модуль fs
Выше мы уже сталкивались с некоторыми методами модуля fs , применяемыми при работе с файловой системой. На самом деле, он содержит ещё много полезного. Напомним, что он не нуждается в установке, для того, чтобы воспользоваться им в программе, его достаточно подключить:
После этого у вас будет доступ к его методам, среди которых отметим следующие, некоторые из которых вам уже знакомы:
- fs.rename()
- fs.renameSync()
- fs.write()
- fs.writeSync()
В Node.js 10 имеется экспериментальная поддержка этих API, основанных на промисах.
Исследуем метод fs.rename() . Вот асинхронная версия этого метода, использующая коллбэки:
При использовании его синхронной версии для обработки ошибок используется конструкция try/catch :
Основное различие между этими вариантами использования данного метода заключается в том, что во втором случае выполнение скрипта будет заблокировано до завершения файловой операции.
Модуль path
Модуль path, о некоторых возможностях которого мы тоже уже говорили, содержит множество полезных инструментов, позволяющих взаимодействовать с файловой системой. Как уже было сказано, устанавливать его не нужно, так как он является частью Node.js. Для того чтобы пользоваться им, его достаточно подключить:
Свойство path.sep этого модуля предоставляет символ, использующийся для разделения сегментов пути ( \ в Windows и / в Linux и macOS), а свойство path.delimiter даёт символ, используемый для отделения друг от друга нескольких путей ( ; в Windows и : в Linux и macOS).
Рассмотрим и проиллюстрируем примерами некоторые методы модуля path .
▍path.basename()
Возвращает последний фрагмент пути. Передав второй параметр этому методу можно убрать расширение файла.
▍path.dirname()
Возвращает ту часть пути, которая представляет имя директории:
▍path.extname()
Возвращает ту часть пути, которая представляет расширение файла:
▍path.isAbsolute()
Возвращает истинное значение если путь является абсолютным:
▍path.join()
Соединяет несколько частей пути:
▍path.normalize()
Пытается выяснить реальный путь на основе пути, который содержит символы, использующиеся при построении относительных путей вроде . , .. и // :
▍path.parse()
Преобразует путь в объект, свойства которого представляют отдельные части пути:
- root : корневая директория.
- dir : путь к файлу, начиная от корневой директории
- base : имя файла и расширение.
- name : имя файла.
- ext : расширение файла.
В результате его работы получается такой объект:
▍path.relative()
Принимает, в качестве аргументов, 2 пути. Возвращает относительный путь из первого пути ко второму, основываясь на текущей рабочей директории:
Как мне проанализировать JSON с помощью Node.js? Есть ли какой-нибудь модуль, который будет проверять и анализировать JSON безопасно?
Вы можете просто использовать JSON.parse .
Определение JSON объекта является частью спецификации ECMAScript 5 . node.js построен на движке Google Chrome V8 , который соответствует стандарту ECMA. Следовательно, node.js также имеет глобальный объект [docs] . JSON
Примечание - JSON.parse может связать текущий поток, потому что это синхронный метод. Поэтому, если вы планируете анализировать большие объекты JSON, используйте потоковый анализатор JSON.
Кто-нибудь знает, почему этого нет в официальной документации? Или, если он есть, где его найти? @snapfractalpop: документация описывает только функции и т. д., которые являются частью node.js. Стандартные функции JavaScript являются частью V8 , на котором построен node.js. Я обновил ответ соответственно. здесь я опубликовал демо-версию, где вы можете посмотреть и поиграть с этим ответом онлайн (пример разбора находится в файле app.js - затем нажмите кнопку запуска и увидите результат в терминале): по ссылке вы можете изменить код и увидеть влияние . Ваш ответ требует предварительного знания синтаксиса JavaScript. Насколько сложно будет показать пример использования? JSON.parse (ул); // удобен для новичков и, следовательно, лучше ответВы можете требовать файлы .json.
Например, если у вас есть config.json файл в том же каталоге, что и файл исходного кода, который вы используете:
или (расширение файла может быть опущено):
обратите внимание , что require это синхронное и читает только файл один раз , следующие вызовы возвращают результат из кэша
Также обратите внимание, что вы должны использовать это только для локальных файлов под вашим абсолютным контролем, так как он потенциально выполняет любой код в файле.
Если вы используете этот метод для анализа файла, обязательно примите во внимание путь для запроса. Например, вам может потребоваться сделать что-то вроде этого: require './file-name-with-no-extension' (например, если файл находится в текущем каталоге) Обратите внимание, что ответ кэшируется. Например, если вы укажете выше требование функции в функции, вызов функции, изменение файла JSON и повторный вызов функции, вы получите старую версию файла JSON. Поймал меня пару раз! Обратите внимание, что require это синхронно. Если вы хотите использовать дружественное асинхронное использование fs.readFile вместо этого JSON.parse Будет ли этот подход обрабатывать файл как JavaScript, таким образом потенциально запуская произвольный код в файле .json? Простое примечание: не забудьте использовать .json расширение! Если ваш файл НЕ имеет .json расширения, require не будет обрабатывать его как файл json.Вы можете использовать JSON.parse() .
Вы должны иметь возможность использовать JSON объект в любой реализации JavaScript, совместимой с ECMAScript 5 . И V8 , на котором построен Node.js, является одним из них.
Вам придется выполнить некоторые файловые операции с fs модулем.
Асинхронная версия
Синхронная версия
Но я не рекомендую это по нескольким причинам:
- require синхронно Если у вас очень большой JSON-файл, он закроет ваш цикл событий. Вам действительно нужно использовать JSON.parse с fs.readFile .
- require будет читать файл только один раз . Последующие обращения к require тому же файлу вернут кэшированную копию. Не очень хорошая идея, если вы хотите прочитать .json файл, который постоянно обновляется. Вы могли бы использовать взломать . Но на данный момент проще использовать fs .
- Если ваш файл не имеет .json расширения, require содержимое файла не будет обрабатываться как JSON.
Шутки в сторону! Использование JSON.parse .
Если вы читаете большое количество .json файлов (и если вы очень ленивы), каждый раз становится неудобно писать шаблонный код. Вы можете сохранить некоторые символы с помощью load-json-file модуля.
Асинхронная версия
Синхронная версия
Если содержимое JSON передается по сети, необходимо использовать потоковый анализатор JSON. В противном случае он свяжет ваш процессор и закроет цикл обработки событий, пока содержимое JSON не будет полностью передано.
Если вы не уверены, что все, что передано, JSON.parse() является допустимым JSON , убедитесь, что JSON.parse() заключили вызов внутрь try/catch блока. Предоставленная пользователем строка JSON может привести к сбою приложения и даже к дырам в безопасности. Убедитесь, что обработка ошибок выполнена, если вы анализируете предоставленный извне JSON.
and could even lead to security holes из любопытства, как? @NickSteele: Однако я изменил «это не рекомендуется» на «я не рекомендую». Я надеюсь, что вы счастливы сейчас. @NickSteele: Учитывая недостатки, которые я перечислил, я не думаю, что это хорошо продуманная функция. Похоже, что некоторые люди думают: «Эй, разве не круто использовать require JSON?» и даже не стал документировать побочные эффекты. Это также означало, что require принимает файлы на двух языках: JavaScript и JSON (нет, они не одинаковы). Так много для SRP. @NickSteele: Да, только для конфига он работает нормально. Но JSON не используется только для конфигурации. Это просто дублирует верхний ответ. Пожалуйста, рассмотрите возможность его удаления; Вы сохраните очки. Этот ответ имеет 50 голосов. Согласно правилу 1% , вероятно, 5000 пользователей потратили время на чтение этого ответа, что ничего не добавляет к верхнему. Тот факт, что ему 3 года, только усугубляет проблему :) Я, например, нашел эту серию комментариев довольно интересной, но сам ответ был пустой тратой моего времени. . Я не уверен, подразумевает ли это, что ответ должен быть удален, потому что тогда я бы не увидел ветку комментариев. Но в противном случае я бы сказал, что да. @DanDascalescu, я считаю, что этот ответ яснее и прямо в точку. Принятый не дает пример использования и сбивает с толку из-за множества ссылок и дополнительных вещей.Еще один пример JSON.parse:
Мне нравится, что этот подход не требует, чтобы файл json был локальным для приложения. Спасибо!Я хотел бы отметить, что есть альтернативы глобальному объекту JSON. JSON.parse и JSON.stringify оба синхронны, поэтому, если вы хотите работать с большими объектами, вы можете проверить некоторые из асинхронных модулей JSON.
Связанная страница теперь помечена как «УСТАРЕЩАЯ» и описывает себя как «выцветшая реликвия».Включить node-fs библиотеку.
Возможно, стоит отметить, что вы должны заключить строку var файла в try / catch на тот случай, если ваш JSON не удастся проанализировать или файл не существует.Так как вы не знаете, что ваша строка на самом деле действительна, я бы поставил ее сначала в попытку. Кроме того, поскольку блоки try catch не оптимизируются узлом, я бы поместил все это в другую функцию:
ИЛИ в "асинхронном стиле"
Я просто хочу отметить, что process.nextTick не является aysnc. Это просто откладывает чтение файла до следующего вызова функции в цикле событий JS. Для асинхронного запуска JSON.parse вы должны использовать поток, отличный от основного потока Node.jsРазбор потока JSON? Использование JSONStream .
Все здесь рассказывали о JSON.parse, поэтому я подумал сказать что-то еще. Есть отличный модуль Connect со многими промежуточными программами, чтобы сделать разработку приложений проще и лучше. Одним из промежуточных программ является bodyParser . Он анализирует JSON, html-формы и т. Д. Существует также специальное промежуточное ПО для анализа только JSON noop .
Посмотрите на ссылки выше, это может быть очень полезно для вас.
как уже упоминалось в других ответах, вы, вероятно, захотите либо потребовать локальный файл json, который, как вы знаете, безопасен и присутствует, например, файл конфигурации:
или использовать глобальный объект JSON для анализа строкового значения в объекте:
обратите внимание, что когда вам требуется файл, его содержимое оценивается, что создает угрозу безопасности в случае, если это не файл json, а файл js.
Вы можете изменить код и увидеть влияние .
Используете JSON для своей конфигурации с Node.js? Прочитайте это и получите навыки настройки более 9000 .
Примечание. Люди, утверждающие, что data = require ('./ data.json'); это угроза безопасности, и люди с ревностным рвением опровергают ответы людей: вы совершенно и совершенно неправы . Попробуйте поместить не-JSON в этот файл . Node выдаст вам ошибку, точно так же, как если бы вы делали то же самое с гораздо более медленным и трудным кодом для ручного чтения файла, а затем с последующим JSON.parse (). Пожалуйста, прекратите распространять дезинформацию; ты делаешь больно миру, а не помогаешь. Узел был разработан, чтобы позволить это; это не угроза безопасности!
Правильные приложения входят в 3+ уровня конфигурации:
- Конфигурация сервера / контейнера
- Конфигурация приложения
- (необязательно) Конфигурация арендатора / сообщества / организации
- Конфигурация пользователя
Большинство разработчиков относятся к конфигурации своего сервера и приложения так, как будто они могут измениться. Не может Вы можете накладывать изменения из более высоких слоев друг на друга, но вы изменяете базовые требования . Некоторые вещи должны существовать! Сделайте так, чтобы ваш конфиг действовал так, как будто он неизменен, потому что некоторые из них, в основном, как ваш исходный код
Если вы не увидите, что многие вещи не изменятся после запуска, это приведет к анти-шаблонам, таким как засорение вашей конфигурации загрузкой блоков try / catch, и притворство, что вы можете продолжить работу без правильно настроенного приложения. Ты не можешь Если вы можете, это относится к уровню конфигурации сообщества / пользователя, а не к уровню конфигурации сервера / приложения. Вы просто делаете это неправильно. Необязательные элементы должны быть расположены сверху, когда приложение завершает загрузку.
Хватит биться головой об стену: ваш конфиг должен быть очень простым .
Посмотрите, как просто настроить такую сложную инфраструктуру, как независимая от протокола и независимой от источника данных служба, с помощью простого файла конфигурации json и простого файла app.js .
контейнер-config.js .
index.js . (двигатель, который питает все)
app.js . (код, обеспечивающий работу службы, не зависящей от протокола и источника данных)
Используя этот шаблон, вы теперь можете загружать файлы конфигурации сообщества и пользователей поверх загруженного приложения, dev ops готов поместить вашу работу в контейнер и масштабировать ее. Вы читаете за мультитенант. Userland изолирован. Теперь вы можете разделить вопросы о том, какой протокол службы вы используете, какой тип базы данных вы используете, и просто сосредоточиться на написании хорошего кода.
Поскольку вы используете слои, вы можете полагаться на единый источник правды для всего в любое время (многоуровневый объект конфигурации) и избегать проверок ошибок на каждом этапе, беспокоясь о "о, черт, как я собираюсь сделать это работать без правильной конфигурации. ".
Читайте также: