, ассоциированная с процессом, определяет начальные разрешения для всех созданных им файлов. Стандартные разрешения
0777
логически пересекаются (AND) с отрицанием
umask
, то есть биты, поднятые в маске, «маскируются» или сбрасываются. Если вам удобнее, можете представлять себе эту операцию как вычитание (без занимания). Следовательно, если задана маска
022
, то все файлы создаются с разрешениями
0755
.
Получить
или установить маску можно с помощью метода
umask
класса
File
. Если ему передан параметр, то он становится новым значением маски (при этом метод возвращает старое значение).
File.umask(0237) # Установить umask.
current_umask = File.umask # 0237
Некоторые биты режима файла (например, бит фиксации — sticky bit) не имеют прямого отношения к разрешениям. Эта тема обсуждается в разделе 10.1.12.
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?
возвращает длину. Но если мы применяем его не в качестве предиката, то значение