Ruby — один из самых популярных языков, используемых в сети. Недавно мы начали новую сессию на Nettuts +, которая познакомит вас с Ruby, а также с отличными фреймворками и инструментами, которые сопровождают разработку на Ruby. Сегодня мы рассмотрим классы Dir
и File
и то, как мы можем использовать их для работы с каталогами и файлами.
Посмотреть скринкаст
Справочники
PWD
Если вы проделали большую работу с терминалом (командная строка AKA, оболочка AKA), вы будете знать, что у него есть понятие текущего каталога, называемого рабочим каталогом. Это папка, в которой вы сейчас находитесь. Всякий раз, когда вы набираете команду, которая использует файл, рабочий каталог будет первым местом, где ваша оболочка ищет файл.
Ruby имеет аналогичное понятие при выполнении кода. Он понимает структуру папок ОС и имеет несколько полезных инструментов для работы с ней.
Итак, как узнать, в какой папке находится скрипт ruby?
1
|
Dir.pwd # «/Users/andrew/Documents»
|
Метод pwd
(печать рабочего каталога) класса Dir
предоставляет нам эту информацию. Если вы находитесь в irb
, вашим рабочим каталогом будет — по умолчанию — папка, в которой вы запустили irb
. Если вы находитесь в скрипте, это будет место, из которого вы вызываете скрипт.
ChDir
Если вы хотите изменить рабочий каталог, вы можете использовать метод chdir
; передайте ему путь к каталогу, в который вы хотите перейти:
1
2
3
|
Dir.chdir «Documents»
Dir.chdir «/users/andrew/Documents»
|
Как видите, строковый параметр может быть как абсолютным, так и относительным путем.
Glob
Если вы ищете определенные файлы в рабочем каталоге ( Dir.pwd
), вы можете получить их, используя метод Dir.glob
. Передайте этот метод «шар»; это шаблон поиска, который находится где-то между статической строкой и полным регулярным выражением. Вы можете использовать звездочку *
в качестве подстановочного знака, как в командной оболочке; Вы можете использовать двойную звездочку **
для рекурсивного сопоставления каталогов. Вы также можете использовать наборы в квадратных скобках, как с регулярными выражениями. Если вам нужно больше, ознакомьтесь с полной документацией . Dir.glob
с возвратом массива … или, вы можете передать ему блок и получить каждое совпадение по одному.
1
2
3
4
5
6
|
# Remember, this runs on the current directory
all_text_files = Dir.glob «*.txt»
Dir.glob(«**/*.[az]») do |filename|
# will match any file in any child directory with a single lower-case letter extension
end
|
новый и открытый
Помимо размещения полезных функций, вы также можете создать экземпляр класса Dir
. Вы передаете ему имя каталога, который хотите использовать; как и для всех функций, которые принимают путь, он может быть абсолютным или относительным.
1
2
|
reciepts = Dir.new «reciepts»
me = Dir.open «/users/andrew»
|
И new
и open
возвращают объект Dir
; Тем не менее, есть еще один способ использовать open
:
1
2
3
|
Dir.open «/users/andrew» do |dir|
# use it here
end
|
Это общее соглашение со многими классами в Ruby; вместо того, чтобы хранить объект Dir
в переменной, вы можете передать его в блок и использовать его оттуда. Это довольно другой стиль кодирования, которого я не видел ни на одном другом языке, но довольно приятно, только если вы привыкнете к нему.
Есть большая вероятность, что когда вы создадите объект Dir
, вам захочется поработать с его содержимым. Есть несколько способов сделать это.
каждый
Предполагая, что some_dir
является объектом Dir
,
1
2
3
|
some_dir.each do |file|
# do something
end
|
Вы можете использовать each
метод в объектах Dir
для итерации по каждому файлу или каталогу, который находится внутри него. Обратите внимание, что вы не получаете объект File
или Dir
; просто строка с названием этого; если вы хотите сделать больше, вам придется создавать соответствующий объект самостоятельно.
записи
Если вы просто хотите увидеть, что находится внутри каталога, вы можете использовать свойство entries
, чтобы получить массив содержимого:
1
|
some_dir.entries # [ «.», «..», «file_one.txt», «another_directory»]
|
Как вы заметите выше, в каталог для каталога входят «.» И «..», указатель на него и его родительский каталог.
файлы
Ruby также предлагает полезный API для работы с файлами.
absolute_path
Когда вы работаете с файлами, вы можете захотеть получить абсолютный путь к одному. Класс File
предлагает именно то, что вам нужно:
1
|
File.absotule_path «plans.txt» # => «/users/andrew/Documents/plans.txt»
|
базовое имя
А как же наоборот? У вас есть абсолютный путь, и вы хотите просто имя файла? Вместо этого используйте basename
1
2
3
|
File.basename(«/users/andrew/Documents/plans.txt») # => «plans.txt»
File.basename(«/users/andrew/Documents/plans.txt», «.txt») # => «plans»
|
Если вы передадите второй строковый параметр, метод будет искать эту строку в конце имени файла и удалит ее, если она там есть; это не должно быть расширение файла, но это очевидное основное использование для этого.
удалять
Очевидное использование этого — удалить файл, который вы передаете в метод:
1
|
File.delete «code.rb»
|
каталог?
Это полезный; Допустим, вы все работаете над записями объекта Dir
, но вам нужны только файлы. File.directory?
Метод вернет true
если передаваемый ему строковый параметр является каталогом, и false
если это файл.
1
2
3
4
5
|
Dir.open(Dir.pwd).each do |filename|
next if File.directory?
# otherwise, process file
end
|
Этот фрагмент open
текущий каталог и передает блок each
методу. each
метод передает записи каталога по одной в блок. Эта первая строка внутри блока может немного смущать вас, если вы не привыкли к Ruby, но посмотрите на это внимательно. Единственная часть, с которой вы не знакомы, это ключевое слово next
, которое пропускает оставшуюся часть блока и переходит к следующей его итерации. Итак, мы говорим: «переходите к следующей записи, если запись, которая у нас есть в данный момент, является каталогом. Если это не каталог, мы можем делать все, что захотим.
новый и открытый
Создание экземпляров класса File
работает так же, как и с Dir
; File.new
возвращает объект File
, тогда как File.open
может вернуть его или передать в блок. Вы также должны передать второй параметр, который решает, как файл будет открыт. В большинстве случаев вы, вероятно, будете использовать это:
- «R»: только для чтения
- «W»: только для записи (перезаписывает что-либо в файле, если файл существует)
- «W +»: чтение и запись (перезаписывает что-либо в файле, если файл существует)
- «A»: только для записи (начинается в конце файла, если файл существует)
Итак, какие методы дает вам экземпляр File
? Ну, эти методы на самом деле происходят из класса IO
, от которого наследуется File
. В большинстве случаев вы будете открывать файл для чтения или записи содержимого, поэтому давайте рассмотрим эту функциональность.
чтение
Прежде чем начать, запомните следующее: как работает файл, после прочтения строки он больше не отображается; вы работаете с файлом. В любой момент вы можете использовать метод f.rewind
чтобы вернуться к началу файла.
Если вы хотите просто прочитать все это, вы можете сделать это с помощью read
.
1
2
3
|
f = File.open(«sample.txt», «r») # assume this file for the next couple of snippets
f.read # => «something\nline 2\na third\nfour!\n5555\nsixy\nsevenly\neight»
|
Тем не менее, вы, вероятно, захотите читать по одной строке за раз; Для этого используйте метод readline
:
1
2
3
4
5
6
7
|
f.rewind # back at the beginning
f.readline # «something\n»
f.readline # «line 2\n»
f.readline # «a third\n»
|
Вы также можете использовать метод gets
вместо readline
.
Есть также метод readlines
, который возвращает массив, в котором строки в виде записей:
1
2
3
|
f.rewind
f.readlines # => [«something\n», «line 2\n», «a third\n», «four!\n», «5555\n», «sixy\n», «sevenly\n», «eight»]
|
Наконец, вы можете использовать each
и передать блок методу для работы с каждой строкой, одну за другой.
1
2
3
4
5
|
f.rewind
f.each do |line|
puts line
end
|
Письмо
Для записи у вас есть два варианта: write
и puts
. Основное отличие состоит в том, что puts
добавляет разрыв строки в конец вашей строки, а write
— нет.
1
2
3
4
5
6
7
8
9
|
f = File.open(«file.txt», «w+»)
f.puts «first line»
f.write «second «
f.write «line»
f.rewind
f.readlines # => [«first line\n», «second line»]
|
Вопрос к тебе
Ну, вот и все для Ruby For Newbies, урок 7. В классах Dir
и File
можно найти еще Dir
-что; проверьте документы для Dir , File и IO для большего количества (класс IO — то, где File наследует его методы экземпляра).
Тем не менее, мне любопытно, откуда вы хотите, чтобы эта серия статей шла дальше: хотите ли вы продолжить работу с языком Ruby, или вы хотите перейти к использованию Ruby в Интернете? Оба направления будут ценны для вас, как для веб-разработчика, поэтому выскажите свое мнение в комментариях!