Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на языке Ruby.docx
Скачиваний:
18
Добавлен:
06.09.2019
Размер:
1.74 Mб
Скачать

10.1.10. Получение и установка временных штампов

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

Получить эту информацию можно тремя разными способами, хотя все они дают один и тот же результат.

Методы mtime, atime и ctime класса File возвращают временные штампы, не требуя предварительного открытия файла или даже создания объекта File.

t1 = File.mtime("somefile")

# Thu Jan 04 09:03:10 GMT-6:00 2001

t2 = File.atime("somefile")

# Tue Jan 09 10:03:34 GMT-6:00 2001

t3 = File.ctime("somefile")

# Sun Nov 26 23:48:32 GMT-6:00 2000

Если файл, представленный экземпляром File, уже открыт, то можно воспользоваться методами этого экземпляра.

myfile = File.new("somefile")

t1 = myfile.mtime

t2 = myfile.atime

t3 = myfile.ctime

А если имеется экземпляр класса File::Stat, то и у него есть методы, позволяющие получить ту же информацию:

myfile = File.new("somefile")

info = myfile.stat

t1 = info.mtime

t2 = info.atime

t3 = info.ctime

Отметим, что объект File::Stat возвращается методом класса (или экземпляра) stat из класса File. Метод класса lstat (или одноименный метод экземпляра) делает то же самое, но возвращает информацию о состоянии самой ссылки, а не файла, на который она ведет. Если имеется цепочка из нескольких ссылок, то метод следует по ней и возвращает информацию о предпоследней (которая уже указывает на настоящий файл).

Для изменения времени доступа и модификации применяется метод utime, которому можно передать несколько файлов. Время можно создать в виде объекта Time или числа секунд, прошедших с точки отсчета.

today = Time.now

yesterday = today - 86400

File.utime(today, today, "alpha")

File.utime(today, yesterday, "beta", "gamma")

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

mtime = File.mtime("delta")

File.utime(Time.now, mtime, "delta")

10.1.11. Проверка существования и получение размера файла

Часто необходимо знать, существует ли файл с данным именем. Это позволяет выяснить метод exist? из модуля FileTest:

flag = FileTest::exist?("LochNessMonster")

flag = FileTest::exists?("UFO")

# exists? является синонимом exist?

Понятно, что такой метод не может быть методом экземпляра File, поскольку после создания объекта файл уже открыт. В классе File мог бы быть метод класса с именем exist?, но его там нет.

С вопросом о том, существует ли файл, связан другой вопрос: а есть ли в нем какие-нибудь данные? Ведь файл может существовать, но иметь нулевую длину — а это практически равносильно тому, что он отсутствует.

Если нас интересует только, пуст ли файл, то в классе File::Stat есть два метода экземпляра, отвечающих на этот вопрос. Метод zero? возвращает true, если длина файла равна нулю, и falseв противном случае.

flag = File.new("somefile").stat.zero?

Метод size? возвращает либо размер файла в байтах, если он больше нуля, либо nil для файла нулевой длины. Не сразу понятно, почему nil, а не 0. Дело в том, что метод предполагалось использовать в качестве предиката, а значение истинности нуля в Ruby — true, тогда как для nil оно равно false.

if File.new("myfile").stat.size?

 puts "В файле есть данные."

else

 puts "Файл пуст."

end

Методы zero? и size? включены также в модуль FileTest:

flag1 = FileTest::zero?("file1")

flag2 = FileTest::size?("file2")

Далее возникает следующий вопрос: «Каков размер файла?» Мы уже видели что для непустого файла метод size? возвращает длину. Но если мы применяем его не в качестве предиката, то значение nil только путает.

В классе File есть метод класса (но не метод экземпляра) для ответа на этот вопрос. Метод экземпляра с таким же именем имеется в классе File::Stat.

size1 = File.size("file1")

size2 = File.stat("file2").size

Чтобы получить размер файла в блоках, а не в байтах, можно обратиться к методу blocks из класса File::Stat. Результат, конечно, зависит от операционной системы. (Метод blksize сообщает размер блока операционной системы.)

info = File.stat("somefile")

total_bytes = info.blocks * info.blksize