Работа с файловой системой в Ruby ч. 3: Стандартная библиотека Ruby: FileUtils и Pathname

июля 4, 2011  |  Published in Ruby, Основы

ruby File APIПродолжая серию статей о File IO в Ruby, мы, в этой статье покопаемся в двух компонентах стандартной библиотеки языка Ruby, которые расширяют ядро Ruby IO API: модуль FileUtils и класс Pathname.

Модуль FileUtils

Модуль FileUtils предоставляет интересный подход к манипуляции файлами путем эмуляции множества команд Unix для работы с файлами и большинства их опций (флагов). То, что вы можете сделать командами типа rm -rf и ln -s может быть выполнено соответственно методами FileUtils.rb_rf и FileUtils.ln_s.

Так как они придерживаются синтаксиса знакомого большинству Ruby-программистов они являются очень простыми для понимания, делая список вызовов методов FileUtils очень похожим на сеанс bash. Пример, что приведен ниже демонстрирует эту схожесть:

require "fileutils"

FileUtils.touch(["some_file.rb", "another_file.rb"])
FileUtils.mkdir("code")
FileUtils.mv(["another_file.rb", "../other_file.rb"], "code")

Dir["code/*"]
#>> ["code/some_file.rb", "code/another_file.rb"]

FileUtils.cp_r("code", "bkp")
FileUtils.rm_r("code")

Dir["code/*"]
#>> []
Dir["bkp/*"]
#>> ["bkp/some_file.rb", "bkp/another_file.rb"]

Как и многие команды Unix, многие методы FileUtils знают как работать с множеством файлов которое передано параметром в виде массива, например, метод FileUtils.cp. Они также могут принимать флаги для изменения своего поведения:

require "fileutils"

FileUtils.rm("a_file.rb") # removes this file
FileUtils.rm(Dir["bkp_*"]) # remove all files that start with bkp
FileUtils.rm(Dir["bkp_*"], :verbose => true) #print the equivalent stmt and remove the bkp files

Класс Pathname

Класс Pathname занимается представлением пути, размещения файла в файловой системе и предоставляет возможности для запрашивания и манипулирования данными пути.

Хотя класс Pathname не так универсален в использовании как модуль FileUtils, класс Pathname может принести больше точности когда вам необходимы тяжелые обходы файловой системы. Pathname также ииспользуется в таких gem’ах как: Sprockets и Carrierwave.

Вы создаете объект типа Pathname просто передавая строку с путем файловой системы в конструктор класса. Вы также можете получить Pathname’ы через объединение двух путей используя Pathname.join или Pathname.+. Кроме того, многие методы класса Pathname возвращают объекты типа Pathname.

require "pathname"

path = Pathname.new("/home/marcos/projects")
#>> Pathname:"/home/marcos/projects"

other = path.join("bragi")
#>> Pathname:"/home/marcos/projects/bragi"

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

require "pathname"

path = Pathname.new("/home/marcos/projects")
path.dirname   # Pathname: "/home/marcos/"
path.basename  # Pathname: "/home/marcos/projects"
path.parent    # Pathname: "/home/marcos/"
path.file?     # false
path.absolute? # true
path.relative? # false

Метод Pathname.ascend обходит все элементы по переданому пути и возвращает экземпляр Pathname для каждого из них. pathname.children возвращает массив со всеми директориями, что находятся в той же родительской директории, что и директория путь которой был передан, а метод Pathname.each_child позволяет пробежаться по этому списку.

require "pathname"

path = Pathname.new("/home/marcos/projects")
path.ascend { |x| puts x }
#>> Pathname: "/home/marcos/projects"
#>> Pathname: "/home/marcos/"
#>> Pathname: "/home/"
#>> Pathname: "/"

path.each_child { |x| puts x }
#>> Pathname: "/home/marcos/projects/bragi"
#>> Pathname: "/home/marcos/projects/mimir"
#>> Pathname: "/home/marcos/projects/guard-clone"

Pathname также предоставляет видимость для многих методов из классов File и Dir, позволяя вам в некоторых случаях писать более чистый код.

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

Оригинал статьи на английском:

Tags: , ,

Leave a Response

Для подсветки кода используйте BB - коды: [language]...[/language], где language может быть: ruby, javascript, css, html.