Node js прочитать все файлы в папке

Обновлено: 06.07.2024

Для работы с файлами в 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() , только вместо имени файла принимают имя директории.

По аналогии с командой dir в MS Windows (а точнее в DOS) или с командой ls в Unix/Linux, мы напишем скрипт на Node.js, реализующий такое же поведение. Он будет получать имя директории и возвращать содержимое директории с некоторой информацией о каждом элементе в этой директории.

Мы уже знаем как получить информацию о файле или директории из inode, таким образом, мы можем просто вызвать fs.stat для каждого элемента в директории.

Этот скрипт получает путь к директории в командной строке (обязательный параметр), а затем перечисляет содержимое этой директории (без рекурсии).

examples/node/read_dir.js

Если вы читали статью о получении системной информации об одном файле, тогда вам уже известна первая часть нашего скрипта. А вот новая интересная часть:

Здесь мы используем метод readdir класса fs, который получает путь и функцию-коллбек в качестве параметров. Метод читает содержимое директории в память, а когда чтение завершено, то вызывает коллбек с двумя параметрами.

Если произошла какая-то ошибка, тогда первый параметр будет содержать информацию об этом. Если все прошло хорошо, тогда второй параметр будет содержать массив со всеми найденными в директории элементами (файлы, директории, символьный ссылки и т.д.).

С этого момента внутри нашей функции-коллбека мы можем просто напечатать весь массив, если мы просто хотим убедиться в успешном выполнении, или пройти циклом по массиву с помощью оператора for и сделать что-нибудь с каждым элементом. К примеру, мы можем напечатать каждый элемент.

Список будет содержать все кроме . (указывает на текущую директорию) и .. (представляет собой родительскую директорию).

Вот как это выглядит:

Подробная информаци о каждом элементе

Теперь, когда мы знаем, как получить содержимое директории, и как получить информацию о файле, мы можем соединить эти две процедуры.

examples/node/list_dir_direct.js

Код достаточно прост и понятен. И он также содержит ошибки, как мы увидим чуть позже.

Внутри коллбека для метода readdir у нас есть цикл for . В этом цикле в каждой итерации мы выводим имя текущего файла (после добавления полного пути директории) - в основном для отладочных целей - и вызываем fs.stat . Этот метод в свою очередь тоже принимает коллбек. Там мы выводим имя файла - в этот раз, как часть результата, и затем выводим размер файла. Мы могли бы вывести все данные о файле как мы это делали в другой статье, но сейчас размера достаточно.

Вывод в консоль:

Отладочный вывод напечатал имена как и ожидалось, но внутри коллбека функции fs.stat() мы снова печатаем одно и тоже имя файла. Сравните результаты:

Количество выведенных строк совпадает с количеством файлов (мы их печатали в том же порядке, как и вызывали fs.stat() ), но по какой-то причине содержимое переменной file было одно и то же для каждого коллбека. Это случилось потому, что переменная file это просто глобальная переменая (с точки зрения коллбека), и в первый раз, когда коллбек был вызван, переменная file содержала уже имя последнего файла в директории.

Таким образом, если мы хотим сочетать имя файла и результат вызова функции fs.stat() , тогда мы должны опираться на порядок вызовов. Но можем ли мы полагаться на него? В этом конкретном случае вызова функции для каждого файла в директории это могло бы сработать как мы ожидаем - вызов функций по порядку. Но в случае более сложных операций, особенно, если есть еще и внутренние коллбеки, мы не можем полагаться на то, что функции будут вызваны в нужном нам порядке - в порядке их инициализации.

Следовательно, нам нужен способ передачи параметра file во внутренний коллбек.

Генерация коллбеков

В этот раз, вместо добавления жестко заданного коллбека, мы будем вызывать функцию generate_callback() , которая будет генерировать для нас коллбеки.

Теперь каждый раз, когда мы вызываем fs.stat() , до того как fs.stat() будет реально выполнен, JavaScript будет вызывать функцию generate_callback() с текущим значением переменной file . Generate_callback будет создавать новую функцию и затем возвращать ее нам. Эта вновь созданная функция станет коллбеком для метода fs.stat() .

examples/node/list_dir_generate.js

Теперь переменная file содержит имя файла, которое было у нее на момент инициализации функции, когда fs.stat() приняла ее в качестве аргумента.

Безимянные генераторы функций

В заключение давайте посмотрим решение без использования внешней функции generate_callback .

Доброго времени суток, друзья. Поговорим сегодня о работе с файлами в Node.js. Для работы с файлами используется модуль fs (сокращение от File System).

В этой статье мы рассмотрим следующие темы:

Для начала работы нам потребуется установленная Node.js. Подробную инструкцию по ее установке вы можете получить (тут).

Прежде чем начать работу с модулем, его следует импортировать в рабочем файле.

Пробежимся по основным методам этого модуля и посмотрим на примерах как с ними можно работать.

Работа с файловыми дескрипторами

Прежде чем двигаться дальше, давайте посмотрим на термины, о которых описано в статье ниже.

Файловый дескриптор — это неотрицательное целое число. Когда создается новый поток ввода-вывода, ядро возвращает процессу, создавшему поток ввода-вывода, его файловый дескриптор (Wikipedia).

Перейдем к примерам.

Ниже я приведу перечень флагов доступа к файлам

Следует помнить, что дескрипторы файлов необходимо закрывать для предотвращения переполнения памяти, а также проблем с производительностью. Выполним данную задачу с помощью метода close() и его синхронного аналога closeSync().

Работа с директориями

Для проверки существующей директории (файла) и доступов к нему в модуле fs применяется метод access

Вторым параметром устанавливается константа режима проверки:

Создание новой папки

Для создания каталогов присутствует асинхронный метод mkdir и синхронный mkdirSync.

Для создания в текущей директории нового каталога, перед путем следует указать переменную __dirname как вариант реализации абсолютного пути, либо воспользоваться метом resolve модуля path.

Чтение содержимого папки

Для получения содержимого директории используются два метода readdir и readdirSync. Первым параметром для методов передается путь директории, содержимое которой нужно получить.

Удаление папки

Удаление директории производится с помощью методов rmdir и rmdirSync. Первым параметром методов является путь удаляемой директории.

Получение системной информации о файле

Каждый файл, который мы загружаем, помимо данных хранит в себе системную информацию. Для получения этой информации можно воспользоваться методом stat() или выбрать синхронный вариант statSync()

Вся информация хранится в получаемом объекте stats. Данный объект хранит в себе методы для получения дополнительной полезной информации.

Перечислю некоторые из этих свойств:

stats.isDirectory() метод позволяет узнать, является ли файл директорией;

stats.isFile() метод возвращает true, если это файл;

stats.isSocket() метод возвращает true, если это сокет;

stats.isSymbolicLink() метод возвращает true, если файл является символьной ссылкой;

stats.size свойство, которое возвращает размер файла;

stats.birthtime возвращает время и дату, когда данный файл был создан.

Модуль path и путь к файлу Node.js

Основной проблемой при работе с файлами и папками в операционных системах является разный синтаксис написания путей их расположения. Для решения этой проблемы в Node.js есть модуль path c набором полезных методов.

Для началы работы с модулем его нужно импортировать.

Получение имени, пути и расширения файла

Предположим, что в папке /temp лежит файл template.txt. Воспользуемся методами модуля path для получения имени файла, пути к нему, а так же его расширения.

Метод basename возвращает наименование файла. Первым параметром передается путь к файлу, вторым параметром (опционально) передается расширение файла, если необходимо получить наименование файла без расширения.

path.basename(file, ‘.txt’) // tempalate

Метод dirname возвращает весь путь директории, где лежит файл и имеет один параметр, в который передается путь к файлу.

Метод extname возвращает расширение переданного файла.

Работа с путями файла

В модуле path есть ряд методов для удобного формирования путей к нужному файлу или директории. Мы не будем рассматривать все методы, а только наиболее часто используемые. Рассмотрим их ниже.

Метод join принимает список параметров, объединяет их в одну строку, используя разделитель, подходящий к конкретной операционной системе, в которой будет исполнятся код.

Метод resolve используется для нахождения абсолютных путей к файлу.

Метод normalize позволяет найти путь к файлу, используя синтаксис переходов (.. и .) по папкам.

Переименование файла или директории

Методы rename() и renameSync() первым параметром принимают путь к файлу, который нужно переименовать. Второй параметр отвечает за новое наименование файла.

Чтение файла

Если вторым параметром не указана кодировка, то возвращается Buffer. Эти методы полностью загружают файлы в память компьютера, что может сильно отразиться на производительности. Если размер файла большой, то стоит воспользоваться потоками fs.createReadStream()

Запись файла

Чтобы перезаписать контент файлов, используются методы writeFile и writeFileSync. Важный момент! Если файла, контент которого нужно перезаписать, не существует, то он будет создан автоматически.

Копирование файла

Методы copyFile() и copyFileSync() первым параметром принимают путь файла для копирования. Второй параметр принимает название пути и нового файла. Третьим параметром является колбэк функция, которая возвращает ошибку.

Удаление файла

Последнее, что мы рассмотрим в этой статье будут методы unlink() и unlinkSync(). Первым параметром методы принимают путь к удаляемому файлу. Второй параметр в методе unlink возвращает колбэк функцию с ошибкой.

Заключение

В данной статье мы разобрали работу Node.js с файлами, на примерах посмотрели основные полезные методы модулей fs и path. Исходный код вы сможете найти тут. Надеюсь данная статья была вам полезна. Учитесь, думайте, пишите код. Удачного кодинга, друзья!

Подписывайтесь на наш канал в Telegram и на YouTube для получения самой последней и актуальной информации.

Я пытаюсь получить список имен всех файлов, присутствующих в каталоге, используя Node.js. Я хочу вывод, который является массивом имен файлов. Как я могу это сделать?

22 ответа

Разница между этими двумя методами заключается в том, что первый метод является асинхронным, поэтому вы должны предоставить функцию обратного вызова, которая будет выполняться после завершения процесса чтения.

Второй является синхронным, он вернет массив имен файлов, но остановит дальнейшее выполнение вашего кода, пока не завершится процесс чтения.

IMO самый удобный способ выполнить такие задачи - использовать инструмент glob. Вот глобальный пакет для node.js. Установить с

Затем используйте подстановочный знак для сопоставления имен файлов (пример взят с сайта пакета)

Асинхронное использование с mz / fs

Модуль mz предоставляет многообещающие версии библиотеки базовых узлов. Использовать их просто. Сначала установите библиотеку .

В качестве альтернативы вы можете написать их в асинхронных функциях в ES7:

Обновление для рекурсивного листинга

Некоторые пользователи указали желание увидеть рекурсивный список (хотя и не в вопросе) . Используйте >. Это тонкая оболочка для mz .

Это TypeScript, опционально рекурсивный, опционально протоколирование ошибок и асинхронное решение. Вы можете указать регулярное выражение для имен файлов, которые вы хотите найти.

Я использовал fs-extra , потому что это простое улучшение супер-набора fs .

Используйте npm список содержимого. Он читает содержимое и под-содержимое данного каталога и возвращает список путей к файлам и папкам.

Ответ выше не выполняет рекурсивный поиск в каталоге. Вот что я сделал для рекурсивного поиска (с помощью прогулки по узлам: npm install walk )

Это сработает и сохранит результат в файле test.txt, который будет находиться в том же каталоге

Если кто-то все еще ищет это, я делаю это:

И его работа очень хорошо для меня

Получить файлы во всех подкаталогах

Если вам нужен объект со структурой каталогов , я настоятельно рекомендую вам проверить дерево каталогов.

Допустим, у вас есть такая структура:

В противном случае, если вы хотите создать объект дерева каталогов с вашими пользовательскими настройками , посмотрите следующий фрагмент. Живой пример виден на этом codeandbox.

Тогда вы можете просто сделать:

Я сделал модуль узла для автоматизации этой задачи: mddir

Узел mddir "../relative/path/"

Для установки: npm установить mddir -g

Чтобы сгенерировать уценку для текущего каталога: mddir

Для генерации для любого абсолютного пути: mkdir / absolute / path

Чтобы сгенерировать относительный путь: mddir

MD-файл генерируется в вашем рабочем каталоге.

В настоящее время игнорирует node_modules и папки .git.

Получить путь к папке npm bin с помощью:

npm config get prefix

Компакт-диск в эту папку

Заварить установить dos2unix

Dos2unix lib / node_modules / mddir / src / mddir.js

Это преобразует окончания строк в Unix вместо Dos

Затем запустите как обычно с: node mddir "../relative/path/".

Пример сгенерированной структуры файла уценки 'directoryList.md'

Вы не говорите, что хотите сделать это рекурсивно, поэтому я предполагаю, что вам нужны только прямые дочерние элементы каталога.

Взял общий подход @ Hunan-Rostomyan, сделал его немного более кратким и добавил excludeDirs аргумент. Расширить с помощью includeDirs было бы тривиально, просто следуйте той же схеме:

Начиная с узла 10.10.0, можно использовать новую опцию withFileTypes для fs.readdir и fs.readdirSync в сочетании с функцией dirent.isDirectory() для фильтрации имен файлов в каталоге. Это выглядит так:

Возвращенный массив имеет вид:

Обратите внимание, что fileList слишком оптимистичен. Для чего-то серьезного, добавьте обработку ошибок.

Чтение файлов async :

Чтение файлов sync :

По вашему вопросу я предполагаю, что вам не нужны имена каталогов, только файлы.

Если вы хотите просто массив путей к файлам, используйте return_object: false :

Вот простое решение, использующее только собственные модули fs и path :

Или асинхронная версия (вместо нее используется fs.readdir ):

Тогда вы просто звоните (для синхронизации версии):

Или асинхронная версия:

Разница в том, как блокирует узлы при выполнении ввода-вывода. Учитывая, что API выше, то же самое, вы можете просто использовать асинхронную версию, чтобы обеспечить максимальную производительность.

Однако есть одно преимущество использования синхронной версии. Некоторый код легче выполнить, как только завершится обход, как в следующем операторе после обхода. В асинхронной версии вам понадобится дополнительный способ узнать, когда вы закончите. Возможно, сначала создайте карту всех путей, а затем перечислите их. Для простых сценариев сборки / утилит (против высокопроизводительных веб-серверов) вы можете использовать синхронизирующую версию без какого-либо ущерба.

Просто наперед: если вы планируете выполнять операции с каждым файлом в каталоге, попробуйте vinyl-fs (который используется gulp, системой потоковой сборки).

Получить sorted имен файлов. Вы можете фильтровать результаты по определенным extension , таким как '.txt' , '.jpg' и так далее.

Рекурсивное чтение папки в NodeJS

Одной из самых частых задач при работе с каталогами (директориями) в NodeJS является их рекурсивное чтение. Что это такое? Например, у вас есть папка, а в ней еще папка, а в ней еще - и так далее. И Вам необходимо прочитать содержимое корневой папки и всех дочерних, причем уровень вложенности может быть сколь угодно произвольным. Для того, чтобы вывести содержимое всех папок как раз и понадобится рекурсия - вызов функцией самой себя.

В примере кода для NodeJS ниже я покажу Вам как этого можно добиться.

Первый пример

/**
* Рекурсивно обходит папку и возвращает все найденные в ней файлы
* в виде одномерного массива абсолютный путей
*
* @param dir Корневая папка
* @returns массив строк - путей к файлам
*/
async function getFiles(dir)

// асинхронно читает содержимое директории
const subfolders = await readdir(dir);

// возвращает список всех путей к файлам
const files = await Promise.all(subfolders.map(async (subfolder) =>

// преобразует путь к файлу из относительного в абсолютный
const res = resolve(dir, subfolder);

// проверяет директория или файл
// если директория - рекурсивно вызывает саму себя
// в противном случае возвращает файл в массив
return (await stat(res)).isDirectory() ? getFiles(res) : res;
>));

// преобразует многомерный полученный массив путей в одномерный
return files.reduce((a, f) => a.concat(f), []);
>


// запускаем с текущей директорией
getFiles(__dirname)
.then(files => console.log(files)) // выводим массив путей
.catch(e => console.error(e)); // или ошибки в консоль

Второй пример:

/**
*
* @param dir папка, с которой начинается сканирование
* @returns
*/
async function getFiles(dir)

// читаем содержимое директории
const dirents = await readdir(dir, < withFileTypes: true >);

// как и в прошлом примере проходимся по папкам
// и, при необходимости рекурсивно вызываем функцию
const files = await Promise.all(dirents.map((dirent) => const res = resolve(dir, dirent.name);
return dirent.isDirectory() ? getFiles(res) : res;
>));

// преобразуем массив файлов в одномерный
return Array.prototype.concat(. files);
>


// тестируем
getFiles(__dirname)
.then(files => console.log(files))
.catch(err => console.error(err))

Вот таким образом, можно рекурсивно обойти все директории и найти полные пути ко всем файлам в NodeJS.


Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

Она выглядит вот так:

Комментарии ( 0 ):

Читайте также: