Linux file system node

Содержание
  1. Роль Inode в файловых системах Linux
  2. Что такое inode?
  3. Сколько существует инодов?
  4. Команды для работы с inode
  5. Номер inode файла
  6. Номер inode каталога
  7. Подведем итог
  8. Tyler Carrigan
  9. Node.js для начинающих: основы работы с файлами
  10. Модуль fs
  11. Создание нового файла
  12. Запись данных в файл
  13. Чтение файла
  14. Переименование файла
  15. Удаление файла
  16. Руководство по Node.js, часть 9: работа с файловой системой
  17. Работа с файловыми дескрипторами в Node.js
  18. Данные о файлах
  19. Пути к файлам в Node.js и модуль path
  20. ▍Получение информации о пути к файлу
  21. ▍Работа с путями к файлам
  22. Чтение файлов в Node.js
  23. Запись файлов в Node.js
  24. Присоединение данных к файлу
  25. Об использовании потоков
  26. Работа с директориями в Node.js
  27. ▍Проверка существования папки
  28. ▍Создание новой папки
  29. ▍Чтение содержимого папки
  30. ▍Переименование папки
  31. ▍Удаление папки
  32. Модуль fs
  33. Модуль path
  34. ▍path.basename()
  35. ▍path.dirname()
  36. ▍path.extname()
  37. ▍path.isAbsolute()
  38. ▍path.join()
  39. ▍path.normalize()
  40. ▍path.parse()
  41. ▍path.relative()
  42. ▍path.resolve()

Роль Inode в файловых системах Linux

Оригинал: Inodes and the Linux filesystem
Автор: Tyler Carrigan (Red Hat)
Дата публикации: 9 июня 2020 г.
Перевод: В.Костромин
Дата перевода: 15 июня 2020 г.

Понять строение файловых систем Linux довольно сложно, особенно когда вы погружаетесь в хитросплетение данных и метаданных. Каждый раз, когда вы запускаете команду ls и видите вывод — перечисление файлов, разрешения, владельцев и т.д. — вы должны понимать, что данные о просматриваемых файлах хранятся где-то отдельно от самих файлов и должны вызываться при обращении к файлу. Иноды усердно работают «за кадром», выполняя работу, которую вы не видите. Давайте же посмотрим, что же такое inode и для чего он нужен.

Что такое inode?

Inode – это сокращение от «index node», по-русски – индексный узел. По сути он представляет собой уникальную порцию метаданных в заданной файловой системе. Эта порция метаданных описывает то, что мы называем файлом. Иноды относятся только к определенной файловой системе, не касаясь других. Как ни странно это может показаться, но все иноды хранятся в общей таблице и это иногда вызывает недоумение. Однако каждая файловая система, смонтированная на вашем компьютере, имеет свои собственные inode. Номер inode может использоваться более одного раза, но никогда не может дважды использоваться одной и той же файловой системой. Идентификатор файловой системы в сочетании с номером инода создает уникальную идентификационную метку.

Сколько существует инодов?

Если вы не хотите связываться с математикой, вы можете пропустить этот раздел. В каждой системе имеется множество inode и есть несколько относящихся к ним числовых значений, которые нужно знать. Прежде всего, хотя это и менее важно, теоретическое максимальное число inode равно 2 ^ 32 (приблизительно 4,3 миллиарда inode). Во-вторых, что гораздо важнее, это число inode в вашей системе. Как правило, количество inode составляет 1:16 от объема файловой системы в КБ. Очевидно, что каждая система отличается, поэтому вам нужно рассчитать это значение самостоятельно.

Команды для работы с inode

Есть хорошая новость для тех, кто не любит математику: для этого есть специальная команда. Чтобы узнать количество inode в вашей системе, вы можете использовать команду df с опцией -i , как показано здесь:

Вы можете видеть, что в этом примере мы запустили команду df -i на файловой системе /dev/sda1 . В этой системе всего имеется 524 288 инодов, но только 312 из них используется (примерно 1%).

Номер inode файла

Мы также можем узнать номер inode конкретного файла. Для этого можно использовать команду ls -i с указанием нужного файла. Например:

Номер inode этого файла — 1459027.

Номер inode каталога

Подобно тому, как мы узнали номер inode файла, мы можем посмотреть и номер inode каталога. Для этого снова используем команду ls -i с некоторыми дополнительными опциями. Например:

Как вы можете видеть, мы использовали опцию -i (inodes), а также -l (long format) и -d (directory). Применение этих флажков позволяет нам получить множество информации о каталоге my_articles, включая номер inode, разрешения, владельцы и т.д.

Подведем итог

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

Надеммся, что этот поверхностный обзор послужит для вас отправной точкой для более глубокого изучения inode.

Tyler Carrigan

Tyler работает менеджером в Enable Sysadmin, является ветераном подводного флота и энтузиастом новых технологий! Он впервые познакомился с Red Hat в 2012 году при использовании основанной на Red Hat Enterprise Linux боевой системы в Центре управления ракетами на подводной лодке USS Georgia.

Источник

Node.js для начинающих: основы работы с файлами

Сегодня мы поговорим о том, как работать с файловой системой средствами Node.js, рассмотрим базовые операции, выполняемые с файлами. К таким операциям относятся следующие:

  • Создание файла
  • Чтение файла
  • Запись данных в файл
  • Удаление файла
  • Переименование файла
Читайте также:  Linux периодический запуск команды

Необходимость в выполнении подобных операций возникает в самых разных ситуациях.

Модуль fs

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

Методы этого модуля представлены в синхронной и асинхронной формах. Функции обратного вызова, передаваемые асинхронным методам, принимают в качестве первого параметра объект ошибки, а в качестве второго — данные, возвращённые при успешном выполнении операции. Рассмотрим пример:

Метод .readFile() , о котором мы ещё поговорим, предназначен для чтения файлов. В этом примере у функции обратного вызова есть два параметра — err и data . В первый параметр попадают ошибки, которые могут возникнуть при попытке чтения файла, во втором оказываются данные, полученные после успешного выполнения операции. Обратите внимание на то, что .readFile() — это асинхронный метод модуля fs . Его синхронная версия называется .readFileSync() . Похожий подход используется и для именования других методов модуля.

Создание нового файла

Начнём с примера:

Здесь метод fs.open() используется для создания нового файла. В качестве первого аргумента он принимает имя файла. Его второй аргумент представляет собой флаг, указывающий системе на то, что именно мы хотим сделать с файлом. В данном случае это флаг w (сокращение от writing), который указывает на то, что мы хотим открыть файл для записи. Метод .open() может принимать различные флаги. Вот некоторые из них:

  1. r : открыть файл для чтения
  2. r+ : открыть файл для чтения и записи
  3. rs : открыть файл для чтения в синхронном режиме
  4. w : открыть файл для записи
  5. a : открыть файл для записи данных в конец файла
  6. a+ : открыть файл для чтения и для записи данных в конец файла

Теперь, прежде чем переходить к следующему примеру, отредактируем только что созданный файл testFile.txt с помощью какого-нибудь текстового редактора. Внесём в него следующий текст:

Запись данных в файл

Поговорим о том, как дописать что-нибудь в файл:

Здесь мы используем метод .appendFile() для добавления данных в конец существующего файла. В качестве первого аргумента этот метод принимает имя файла, в качестве второго — данные, которые нужно добавить в конец файла. Третий аргумент — это, как обычно, функция обратного вызова.

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

Существует и другой способ записи данных в файл. Он подразумевает использование метода .writeFile() . Этот метод очень похож на .appendFile() , но у него есть одно важное отличие. Дело в том, что с помощью метода .appendFile() мы добавляем в файл новые данные после тех данных, которые в нём уже есть. А при использовании метода .writeFile() содержимое файла заменяется на новое. Испытаем этот метод:

После успешного выполнения операции в файле окажется следующий текст:

Как видно, содержимое файла полностью заменено новым.

Чтение файла

Для чтения файлов модуль fs предоставляет метод .readFile() , пример использования которого мы уже видели. В качестве первого параметра он принимает имя файла, в качестве второго — кодировку. Третий параметр — функция обратного вызова. Попытаемся вывести в консоль содержимое файла testFile.txt с помощью этого метода:

Вот что у нас получится.

Данные файла, выведенные в консоль

Теперь поговорим о переименовании файлов.

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

Для переименования файлов используется метод .rename() :

Первый аргумент метода представляет собой имя существующего файла, второй — новое имя этого файла. После успешного вызова этого метода файл testFile.txt превращается в newTestFile.txt .

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

Для удаления файлов используется метод .unlink() :

Источник

Руководство по Node.js, часть 9: работа с файловой системой

Сегодня, в девятой части перевода руководства по Node.js, мы поговорим о работе с файлами. В частности, речь пойдёт о модулях fs и path — о файловых дескрипторах, о путях к файлам, о получении информации о файлах, об их чтении и записи, о работе с директориями.

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

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

Дескриптор можно получить, воспользовавшись для открытия файла асинхронным методом open() из модуля fs :

Обратите внимание на второй параметр, r , использованный при вызове метода fs.open() . Это — флаг, который сообщает системе о том, что файл открывают для чтения. Вот ещё некоторые флаги, которые часто используются при работе с этим и некоторыми другими методами:

  • r+ — открыть файл для чтения и для записи.
  • w+ — открыть файл для чтения и для записи, установив указатель потока в начало файла. Если файл не существует — он создаётся.
  • a — открыть файл для записи, установив указатель потока в конец файла. Если файл не существует — он создаётся.
  • a+ — открыть файл для чтения и записи, установив указатель потока в конец файла. Если файл не существует — он создаётся.

Файлы можно открывать и пользуясь синхронным методом fs.openSync() , который, вместо того, чтобы предоставить дескриптор файла в коллбэке, возвращает его:

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

Читайте также:  Как включить ножницы windows

Данные о файлах

С каждым файлом связан набор данных о нём, исследовать эти данные можно средствами 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() — возвращает расширение файла.

Узнать имя файла без расширения можно, вызвав метод .basename() и передав ему второй аргумент, представляющий расширение:

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

Несколько частей пути можно объединить, используя метод 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() . В этом примере осуществляется чтение содержимого папки — то есть — сведений о том, какие файлы и поддиректории в ней имеются, и возврат их относительных путей:

Читайте также:  Как вспомнить свой пароль от windows

Вот так можно получить полный путь к файлу:

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

▍Переименование папки

Для переименования папки можно воспользоваться методами fs.rename() и fs.renameSync() . Первый параметр — это текущий путь к папке, второй — новый:

Переименовать папку можно и с помощью синхронного метода fs.renameSync() :

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

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

Метод remove() из пакета fs-extra умеет удалять папки, в которых уже что-то есть.

Установить этот модуль можно так:

Вот пример его использования:

Его методами можно пользоваться в виде промисов:

Допустимо и применение конструкции async/await:

Модуль fs

Выше мы уже сталкивались с некоторыми методами модуля fs , применяемыми при работе с файловой системой. На самом деле, он содержит ещё много полезного. Напомним, что он не нуждается в установке, для того, чтобы воспользоваться им в программе, его достаточно подключить:

После этого у вас будет доступ к его методам, среди которых отметим следующие, некоторые из которых вам уже знакомы:

  • fs.access() : проверяет существование файла и возможность доступа к нему с учётом разрешений.
  • fs.appendFile() : присоединяет данные к файлу. Если файл не существует — он будет создан.
  • fs.chmod() : изменяет разрешения для заданного файла. Похожие методы: fs.lchmod() , fs.fchmod() .
  • fs.chown() : изменяет владельца и группу для заданного файла. Похожие методы: fs.fchown() , fs.lchown() .
  • fs.close() : закрывает дескриптор файла.
  • fs.copyFile() : копирует файл.
  • fs.createReadStream() : создаёт поток чтения файла.
  • fs.createWriteStream() : создаёт поток записи файла.
  • fs.link() : создаёт новую жёсткую ссылку на файл.
  • fs.mkdir() : создаёт новую директорию.
  • fs.mkdtemp() : создаёт временную директорию.
  • fs.open() : открывает файл.
  • fs.readdir() : читает содержимое директории.
  • fs.readFile() : считывает содержимое файла. Похожий метод: fs.read() .
  • fs.readlink() : считывает значение символической ссылки.
  • fs.realpath() : разрешает относительный путь к файлу, построенный с использованием символов . и .. , в полный путь.
  • fs.rename() : переименовывает файл или папку.
  • fs.rmdir() : удаляет папку.
  • fs.stat() : возвращает сведения о файле. Похожие методы: fs.fstat() , fs.lstat() .
  • fs.symlink() : создаёт новую символическую ссылку на файл.
  • fs.truncate() : обрезает файл до заданной длины. Похожий метод: fs.ftruncate() .
  • fs.unlink() : удаляет файл или символическую ссылку.
  • fs.unwatchFile() : отключает наблюдение за изменениями файла.
  • fs.utimes() : изменяет временную отметку файла. Похожий метод: fs.futimes() .
  • fs.watchFile() : включает наблюдение за изменениями файла. Похожий метод: fs.watch() .
  • fs.writeFile() : записывает данные в файл. Похожий метод: fs.write() .

Интересной особенностью модуля fs является тот факт, что все его методы, по умолчанию, являются асинхронными, но существуют и их синхронные версии, имена которых получаются путём добавления слова Sync к именам асинхронных методов.

  • 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 пути. Возвращает относительный путь из первого пути ко второму, основываясь на текущей рабочей директории:

▍path.resolve()

Находит абсолютный путь на основе переданного ему относительного пути:

Источник

Оцените статью