Работа с файловой системой в Ruby ч. 2: Класс Dir
июня 30, 2011 | Published in Ruby, Основы | 1 Comment
Продолжая серию о File IO API в Ruby, сегодня мы рассмотрим класс Dir.
Класс Dir
Основная направленность класса Dir — предоставить пользователю возможность запрашивания, обхода и фильтрации по директориям файловой системы. Данный клас предоставляет несколько базовых методов для создания и удаления директорий. Давайте рассмотрим этот его функционал в первую очередь.
Создание директорий
Вы можете создать новую директорию в вашей файловой системе просто передав желаемый путь к ней (полный или относительный) в качестве аргумента в метод Dir.mkdir. Этот метод вызовет ошибку Errno::EEXIST если такая директория уже существует, или SystemCallError если директория не может быть создана в следствии ограниченых прав доступа.
Все относительные пути (включая и те, что вы передаете в методы класса File) происходят из пути к текущей рабочей директории, доступ к кодорой можно получить через метод Dir.pwd (pwd — print work directory). Вы можете изменить рабочую директорию через метод Dir.chdir (chdir — change directory). Для упрощения прыгания между рабочими дииректориями вы можете передать блок кода в метод chdir и рабочая директория будет изменена после его выполнения.
Dir.pwd >> "/home/marcos/code" Dir.mkdir("test") Dir.chdir("test") do Dir.pwd >> "/home/marcos/code/test" File.new("file.rb", "w") end Dir.pwd >> "/home/marcos/code"
Удаление директории
Для удаления директории вам следует передать путь к ней в метод Dir.rmdir (rmdir — remove directory), этот метод также имеет синоним — метод unlink. Эти методы удаляют только пустые директории, если же удаляемая директория содержит что-нибудь, то будет вызвана ошибка SystemCallError. Вы можете получить более мощный инструмент работы с директориями используя класс FileUtils, который мы рассмотрим в следующей статье.
Обход содержимого директории
Класс Dir предоставляет два метода для обхода содержимого директорий, это методы Dir.entries и Dir.glob.
Dir#entries возвращает массив с именами всего содержимого директории, включая текущий путь («.»), родительскую директорию («..») и все скрытые файлы (в linux это все те, в начале имен которых стоит точка). Те же правила относятся и к методу each, который возвращает все содержимое и действует на основе методов из модуля Enumerable.
Метод #entries может вызывать раздражение если вы желаете работать только с файлами, как то продемонстрировано в следующем примере, где мы пытаемся (в очень хитроумный способ) удалить все файлы из определенной директории.
d = Dir.new("/home/marcos/code") d.entries.each do |e| next if e =~ /^\./ file = File.join(d.path, e) File.delete(file) if File.file?(file) end
Гораздо более удобный способ обхода файлов в директории — использовать метод .glob, или очень похожий метод []. Эти методы принимают шаблон и возвращают массив с путями всех видимых файлов, которые соответствуют шаблону.
Шаблоны основаны на специальном кратком синтаксисе, где «*» представляет любое число групповых символов, «**» представляет все дочерние директории (их проверка производится рекурсивно) и «?» представляет один групповой символ.
"*" #все файлы текущей директории "help.*" #все файлы с именем help и любым расширением "*/**/*.rb" #все файлы с расширением rb, из текущей и вложенных директорий
С этой техникой наш маленький пример становися еще более кратким:
Dir["/home/marcos/code/*"].each { |f| File.delete(f) if File.file?(f) }
Метод Dir.glob также принимает флаги (в том числе операторы) для настройки поведения, как, например File::FNM_DOTMATCH который включает скрытые файлы в результат поиска.
Dir.glob("rakefile") >> [] Dir.glob("rakefile", File::FNM_CASEFOLD) >> ["/home/marcos/code/Rakefile"]
Оригинал статьи на английском:
июля 1, 2011 at 08:41 (#)
проще сразу сделать перево всего