Ruby File I/O
Открытие потоков
Перед осуществлением ввода или вывода должен существовать IO-объект, из которого будут считываться или в который будут записываться данные. В классе IO определяются фабричные методы new, open, рореп и piре, но это низкоуровневые методы, чья работа зависит от применяемой операционной системы, далее рассматриваются наиболее распространенные способы получения IO-объектов.
Объект ввода-вывода (IO-объект) — это поток данных: источник байтов или символов, из которого можно производить считывание, или приемник байтов или символов, в который можно производить запись. Класс File является подклассом класса IO. IO-объекты также представляют потоки «стандартного входа» и «стандартного выхода», используемые для чтения из и записи в консольное устройство. Модуль stringio, принадлежащий стандартной библиотеке, позволяет создавать потоковые оболочки вокруг строковых объектов. И наконец, сокет-объекты, используемые при работе с сетями, также являются IО-объектами.
Режим Описание
" г " Открытие для чтения. Этот режим используется по умолчанию
"г+ " Открытие для чтения и записи с начала файла. Выдает сбой, если файл не существует
"w" Открытие для записи. Создает новый или усекает существующий файл
"w+" То же, что и "w", но допускается также и чтение файла
"а" Открытие для записи, но с добавлением в конец файла, если он уже существует
"а+" То же, что и "а", но допускается также и чтение файла
Ruby предоставляет целый набор I/O методов, реализованных в модуле ядра. Все методы ввода-вывода являются производными от класса IO. Класс IO предоставляет все основные методы, такие как: read, write, gets, puts, readline, getc, and printf.
The puts Statement
Оператор puts указывает программе отобразить значение, хранящееся в переменной. Это добавит новую строку в конец каждой записываемой строки.
Пример:
#!/usr/bin/ruby
val1 = "This is variable one"
val2 = "This is variable two"
puts val1
puts val2
Это даст такой результат:
This is variable one
This is variable two
The gets Statement
Оператор gets может использоваться для получения данных со стандартного потока ввода STDIN (в нашем случае это клавиатура).
Пример:
В следующем коде показано, как использовать оператор gets. Этот код предложит пользователю ввести значение, которое будет сохранено в переменной val и в итоге будет напечатано в STDOUT (в нашем случае это экран).
#!/usr/bin/ruby
puts "Enter a value :"
val = gets
puts val
Получится что то типа этого:
Enter a value :
ruby stdout
ruby stdout
The putc Statement
В отличие от оператора puts, который выводит всю строку на экран, оператор putc может использоваться для вывода одного символа за раз.
Пример:
#!/usr/bin/ruby
str = "Hello Ruby!"
putc str
И в итоге:
H
The print Statement
Оператор print это почти оператор puts, с одним не мало важным отличием, которое состоит в том, что оператор puts переходит на следующую строку после печати содержимого, тогда как с оператором print курсор располагается на той же строке.
Пример:
#!/usr/bin/ruby
print "Hello World"
puts "Good Morning"
Что выведет на экран следующее:
Hello WorldGood Morning
Открытие и закрытие файлов
До сих пор мы эксперементировали с стандартным вводом и выводом. Теперь посмотрим, как работать с реальными файлами данных.
Метод File.new
Вы можете создать объект File, используя метод File.new для чтения или записи, или того и другого, в зависимости от режима строки. Наконец, вы можете использовать метод File.close, чтобы закрыть этот файл.
Синтакс:
aFile = File.new("filename", "mode")
# ... process the file
aFile.clos
Метод File.open
Вы можете использовать метод File.open для создания нового файлового объекта и присвоения этого файлового объекта файлу. Однако между методами File.open и File.new есть одно различие. Разница в том, что метод File.open может быть связан с блоком, тогда как вы не можете сделать то же самое, используя метод File.new.
Как и в других языках, например Python работа с файлами осуществляется через специальный абстрактный файловый объект. В зависимости от способа создания такого объекта, он может быть привязан как к физическому файлу на диске, так и другому устройству, поддерживающему схожие операции (стандартный ввод/вывод и пр.).
File.open("filename", "mode") do |aFile|
# ... process the file
end
Чтение и запись файлов
Те же методы, которые мы использовали для «простого» ввода-вывода, доступны для всех файловых объектов. Итак, get читает строку из стандартного ввода, а aFile.gets читает строку из файлового объекта aFile.
Однако объекты ввода-вывода предоставляют дополнительный набор методов доступа, облегчающих нашу жизнь.
Метод sysread
Вы можете использовать метод sysread для чтения содержимого файла. Вы можете открыть файл в любом из режимов при использовании метода sysread.
Например:
Создадим текстовой файл, длиной 30 символов:
$ cat > input.txt
The sysread Method for example
^C
И собственно код Ruby, демонстрирующий метод sysread:
#!/usr/bin/ruby
aFile = File.new("input.txt", "r")
if aFile
content = aFile.sysread(23)
puts content
else
puts "Unable to open file!"
end
В итоге:
The sysread Method for
Оператор sysread выведет первые 23 символа файла, как и задано. Указатель файла теперь будет помещен на 24-й символ в файле.
Метод syswrite
Вы можете использовать метод syswrite для записи содержимого в файл.
Например, создадим пустой файл
> input_1.txt
И собственно код Ruby, демонстрирующий метод syswrite:
#!/usr/bin/ruby
aFile = File.new("input_1.txt", "r+")
if aFile
aFile.syswrite("ABCDEF")
else
puts "Unable to open file!"
end
И в итоге:
vim input_1.txt
ABCDEF
Метод each_byte
Этот метод принадлежит к классу File. Метод each_byte всегда связан с блоком. Рассмотрим следующий пример кода:
Создадим файл:
cat > input_2.txt
testing purpose: each_byte Method
^C
Создадим код Ruby:
#!/usr/bin/ruby
aFile = File.new("input_2.txt")
if aFile
aFile.each_byte {|ch| putc ch; putc ?. }
else
puts "Unable to open file!"
end
Результат:
t.e.s.t.i.n.g. .p.u.r.p.o.s.e.:. .e.a.c.h._.b.y.t.e. .M.e.t.h.o.d.
Символы передаются один за другим в переменную ch и затем отображаются на экране
Метод IO.readlines
Класс File является подклассом класса IO. Класс IO также имеет несколько методов, которые можно использовать для управления файлами. Один из методов класса IO - IO.readlines. Этот метод по очереди возвращает содержимое файла. В следующем коде показано использование метода IO.readlines:
Создадим файл;
cat > input_3.txt
0. testing purpose: each_byte Method
1. testing purpose: IO.readlines Method
2. testing purpose: IO.foreach Method
^C
Напишем код:
#!/usr/bin/ruby
arr = IO.readlines("input_3.txt")
puts arr[0]
puts arr[1]
Просмотрим результат:
0. testing purpose: each_byte Method
1. testing purpose: IO.readlines Method
Метод IO.foreach
Этот метод также возвращает вывод построчно. Разница между методом IO.foreach и методом IO.readlines заключается в том, что метод IO.foreach связан с блоком. Однако, в отличие от метода IO.readlines, метод foreach не возвращает массив. Например:
#!/usr/bin/ruby
IO.foreach("input_3.txt"){|block| puts block}
Этот код будет передавать содержимое файла построчно в блок переменных, а затем вывод будет отображаться на экране.
Результат:
0. testing purpose: each_byte Method
1. testing purpose: IO.readlines Method
2. testing purpose: IO.foreach Method
Переименование и удаление файлов
Вы можете переименовывать и удалять файлы программно с помощью Ruby с посредством методов переименования и удаления.4
Ниже приведен пример переименования существующего файла input.txt.:
#!/usr/bin/ruby
# Rename a file from input.txt to input_4.txt
File.rename( "input.txt", "input_4.txt" )
Далее пример удаления input_4.txt:
#!/usr/bin/ruby
# Delete file input_4.txt
File.delete("input_4.txt")
File Modes and Ownership
Используйте метод chmod с маской, чтобы изменить permissions/access list для файла
Ниже приведен пример изменения режима существующего файла test.txt на значение маски.
#!/usr/bin/ruby
file = File.new( "test.txt", "w" )
file.chmod( 0755 )
File Inquiries
Следующая команда проверяет, существует ли файл перед его открытием
#!/usr/bin/ruby
File.open("file.rb") if File::exists?( "file.rb" )
Следующая команда запрашивает, действительно ли файл является файлом
#!/usr/bin/ruby
# This returns either true or false
File.file?( "text.txt" )
Следующая команда выясняет, является ли данное имя файла каталогом
#!/usr/bin/ruby
# a directory
File::directory?( "/usr/local/bin" ) # => true
# a file
File::directory?( "file.rb" ) # => false
Следующая команда определяет, доступен ли файл для чтения, записи или выполнения
#!/usr/bin/ruby
File.readable?( "test.txt" ) # => true
File.writable?( "test.txt" ) # => true
File.executable?( "test.txt" ) # => false
Следующая команда определяет, имеет ли файл нулевой размер или нет
#!/usr/bin/ruby
File.zero?( "test.txt" ) # => true
Следующая команда возвращает размер файла
#!/usr/bin/ruby
File.size?( "text.txt" ) # => 1002
Следующая команда может использоваться для определения типа файла
#!/usr/bin/ruby
File::ftype( "test.txt" ) # => file
Метод ftype определяет тип файла, возвращая один из следующих − file, directory, characterSpecial, blockSpecial, fifo, link, socket, or unknown.
Следующая команда может использоваться, чтобы узнать, когда файл был создан, изменен или последний раз был осуществлен доступ к нему:
$ irb
irb(main):001:0> File::ctime( "ruby_9.rb" ) #=> 2020-08-26 12:20:50.672461621 +0300
irb(main):002:0> File::mtime( "ruby_9.rb" ) #=> 2020-08-26 12:20:50.636461623 +0300
irb(main):003:0> File::atime( "ruby_9.rb" ) #=> 2020-08-26 12:21:01.628461061 +0300
irb(main):004:0> File::ftype( "ruby_9.rb" ) #=> "file"
irb(main):005:0> File.size?( "ruby_9.rb" ) #=> 958
irb(main):004:0>
Directories in Ruby
Все файлы содержатся в разных каталогах, и Ruby без проблем справляется с ними. В то время как класс File обрабатывает файлы, каталоги обрабатываются классом Dir.
Navigating Through Directories
Чтобы сменить каталог в программе Ruby, используйте Dir.chdir следующим образом. В этом примере текущий каталог изменяется на /usr/bin
Dir.chdir("/usr/bin")
Вы можете узнать текущий каталог с помощью Dir.pwd
puts Dir.pwd # This will return something like /usr/bin
Вы можете получить список файлов и каталогов в определенном каталоге, используя Dir.entries
puts Dir.entries("/usr/bin").join(' ')
Dir.entries возвращает массив со всеми записями в указанном каталоге. Dir.foreach предоставляет ту же функцию
Dir.foreach("/usr/bin") do |entry|
puts entry
end
Еще более краткий способ получения списков каталогов - использовать метод массива классов Dir
$ irb
irb(main):001:0> Dir["/home/dell/*"]
=> ["/home/dell/ruby_29.rb", "/home/dell/ruby_14.rb", "/home/dell/ruby_32.rb", "/home/dell/ruby_36.rb", "/home/dell/Telegram", "/home/dell/ruby_11.rb", "/home/dell/ruby_20.rb", "/home/dell/ruby_8.rb", "/home/dell/xsudoky-1.0.7.tar.gz", "/home/dell/fgf", "/home/dell/vmware", "/home/dell/Изображения", "/home/dell/Рабочий стол", "/home/dell/ruby_7.rb", "/home/dell/ruby_24.rb", "/home/dell/\\", "/home/dell/Загрузки", "/home/dell/ruby_25.rb", "/home/dell/ruby_34.rb", "/home/dell/xcv.rb", "/home/dell/ruby_3.rb", "/home/dell/input_1.txt", "/home/dell/Шаблоны", "/home/dell/ruby_18.rb", "/home/dell/ruby_4.rb", "/home/dell/Музыка", "/home/dell/ruby_21.rb", "/home/dell/input_4.txt", "/home/dell/ruby_23.rb", "/home/dell/ruby_2.rb", "/home/dell/Документы", "/home/dell/ruby_26.rb", "/home/dell/lxc-rest", "/home/dell/ruby_1.rb", "/home/dell/ruby_22.rb", "/home/dell/ruby_10.rb", "/home/dell/xsudoky-1.0.7", "/home/dell/ruby_13.rb", "/home/dell/Видео", "/home/dell/ruby_5.rb"]
irb(main):002:0>
Creating a Directory
Dir.mkdir можно использовать для создания каталогов
Dir.mkdir("mynewdir")
Вы также можете установить разрешения для нового каталога (а не того, который уже существует) с помощью mkdir
NOTE − The mask 755 sets permissions owner, group, world [anyone] to rwxr-xr-x where r = read, w = write, and x = execute.
Dir.mkdir( "mynewdir", 755 )
Deleting a Directory
Dir.delete можно использовать для удаления каталога. Dir.unlink и Dir.rmdir выполняют ту же функцию и предоставляются для удобства.
Dir.delete("testdir")
Creating Files & Temporary Directories
Временные файлы - это файлы, которые могут быть созданы на короткое время во время выполнения программы, но не являются постоянным хранилищем информации. Dir.tmpdir предоставляет путь к временному каталогу в текущей системе, хотя этот метод по умолчанию недоступен. Чтобы сделать Dir.tmpdir доступным, необходимо использовать require 'tmpdir'.
Вы можете использовать Dir.tmpdir с File.join для создания независимого от платформы временного файла -
tempfilename = File.join(Dir.tmpdir, "tingtong")
tempfile = File.new(tempfilename, "w")
tempfile.puts "This is a temporary file"
tempfile.close
File.delete(tempfilename)
Этот код создает временный файл, записывает в него данные и удаляет его. Стандартная библиотека Ruby также включает библиотеку под названием Tempfile, которая может создавать для вас временные файлы -
require 'tempfile'
f = Tempfile.new('tingtong')
f.puts "Hello"
puts f.path
f.close
Built-in Functions
Вот встроенные функции Ruby для обработки файлов и каталогов