Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

10.1.5. Работа с двоичными файлами

Когда-то давно программисты на языке С включали в строку указания режима символ

"b"
для открытия файла как двоичного. (Вопреки распространенному заблуждению, это относилось и к ранним версиям UNIX.) Как правило, эту возможность все еще поддерживают ради совместимости, но сегодня с двоичными файлами работать не так сложно, как раньше. Строка в Ruby может содержать двоичные данные, а для чтения двоичного файла не нужно никаких специальных действий.

Исключение составляет семейство операционных систем Windows, в которых различие все еще имеет место. Основное отличие двоичных файлов от текстовых на этой платформе состоит в том, что в двоичном режиме конец строки не преобразуется в один символ перевода строки, а представляется в виде пары «возврат каретки — перевод строки». Еще одно важное отличие — интерпретация символа control-Z как конца файла в текстовом режиме:

# Создать файл (в двоичном режиме).

File.open("myfile","wb") {|f| f.syswrite("12345\0326789\r") }

#Обратите внимание на восьмеричное 032 (^Z).

# Читать как двоичный файл.

str = nil

File.open("myfile","rb") {|f| str = f.sysread(15) )

puts str.size # 11

# Читать как текстовый файл.

str = nil

File.open("myfile","r") {|f| str = f.sysread(15) }

puts str.size # 5

В следующем фрагменте показано, что на платформе Windows символ возврата каретки не преобразуется в двоичном режиме:

# Входной файл содержит всего одну строку: Строка 1.

file = File.open("data")

line = file.readline # "Строка 1.\n"

puts "#{line.size} символов." # 10 символов,

file.close

file = File.open("data","rb")

line = file.readline # "Строка 1.\r\n"

puts "#{line.size} символов." # 11 символов.

file.close

Отметим, что упомянутый в коде метод

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

file = File.open("data")

file.binmode

line = file.readline # "Строка 1.\r\n"

puts {line.size} символов." # 11 символов.

file.close

При необходимости выполнить низкоуровневый ввод/вывод можете воспользоваться методами

sysread
и
syswrite
. Первый принимает в качестве параметра число подлежащих чтению байтов, второй принимает строку и возвращает число записанных байтов. (Если вы начали читать из потока методом
sysread
, то никакие другие методы использовать не следует. Результаты могут быть непредсказуемы.)

input = File.new("infile")

output = File.new("outfile")

instr = input.sysread(10);

bytes = output.syswrite("Это тест.")

Отметим, что метод

sysread
возбуждает исключение
EOFError
при попытке вызвать его, когда достигнут конец файла (но не в том случае, когда конец файла встретился в ходе успешной операции чтения). Оба метода возбуждают исключение
SystemCallError
при возникновении ошибки ввода/вывода.

При работе с двоичными данными могут оказаться полезны метод

pack
из класса
Array
и метод
unpack
из класса
String
.

10.1.6. Блокировка файлов

В тех операционных системах, которые поддерживают такую возможность, метод

flock
класса
File
блокирует или разблокирует файл. Вторым параметром может быть одна из констант
File::LOCK_EX
,
File::LOCK_NB
,
File::LOCK_SH
,
File::LOCK_UN
или их объединение с помощью оператора ИЛИ. Понятно, что многие комбинации не имеют смысла; чаще всего употребляется флаг, задающий неблокирующий режим.

file = File.new("somefile")

file.flock(File::LOCK_EX) # Исключительная блокировка; никакой другой

# процесс не может обратиться к файлу.

file.flock(File::LOCK_UN) # Разблокировать.

file.flock(File::LOCK_SH) # Разделяемая блокировка (другие

# процессы могут сделать то же самое).

file.flock(File::LOCK_UN) # Разблокировать.

locked = file.flock(File::LOCK_EX | File::LOCK_NB)

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

# не получилось; в таком случае переменная locked будет равна false.

Для семейства операционных систем Windows эта функция не реализована.

10.1.7. Простой ввод/вывод

Вы уже знакомы с некоторыми методами ввода/вывода из модуля

Kernel
; мы вызывали их без указания вызывающего объекта. К ним относятся функции
gets
и
puts
, а также
print
,
printf
и
p
(последний вызывает метод объекта
inspect
, чтобы распечатать его в понятном для нас виде).

Но есть и другие методы, которые следует упомянуть для полноты. Метод

putc
выводит один символ. (Парный метод
getc
не реализован в модуле
Kernel
по техническим причинам, однако он есть у любого объекта класса
IO
). Если параметром является объект
String
, то печатается первый символ строки.

putc(?\n) # Вывести символ новой строки.

putc("X") # Вывести букву X.

Интересный вопрос: куда направляется вывод, если эти методы вызываются без указания объекта? Начнем с того, что в среде исполнения Ruby определены три глобальные константы, соответствующие трем стандартным потокам ввода/вывода, к которым мы привыкли в UNIX. Это

STDIN
,
STDOUT
и
STDERR
. Все они имеют тип
IO
.

Поделиться:
Популярные книги

Бестужев. Служба Государевой Безопасности. Книга вторая

Измайлов Сергей
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая

Ректор

Назимов Константин Геннадьевич
3. Врачеватель
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ректор

Сотник

Вязовский Алексей
2. Индийский поход
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сотник

Атаман. Гексалогия

Корчевский Юрий Григорьевич
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
8.15
рейтинг книги
Атаман. Гексалогия

Убивать чтобы жить 5

Бор Жорж
5. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 5

Газлайтер. Том 9

Володин Григорий
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9

Гримуар темного лорда VIII

Грехов Тимофей
8. Гримуар темного лорда
Фантастика:
боевая фантастика
альтернативная история
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Гримуар темного лорда VIII

Отвергнутая невеста генерала драконов

Лунёва Мария
5. Генералы драконов
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Отвергнутая невеста генерала драконов

Неправильный лекарь. Том 2

Измайлов Сергей
2. Неправильный лекарь
Фантастика:
городское фэнтези
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Неправильный лекарь. Том 2

Последний Герой. Том 1

Дамиров Рафаэль
1. Последний герой
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
5.00
рейтинг книги
Последний Герой. Том 1

Страж Каменных Богов

Свержин Владимир Игоревич
3. Трактир "Разбитые надежды"
Фантастика:
боевая фантастика
5.00
рейтинг книги
Страж Каменных Богов

Первый среди равных. Книга II

Бор Жорж
2. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга II

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Газлайтер. Том 27

Володин Григорий Григорьевич
27. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 27