класс File
A File — это абстракция любого файла, доступного программе, и тесно связана с классом IO. File включает методы модуля FileTest в качестве методов класса, позволяя, например, File.exist?("foo").
В описании методов File, разрешения доступа — это специфичная для платформы настройка битов, указывающая разрешения файла. В системах на базе Unix разрешения рассматриваются как набор из трёх октетов: для владельца, группы и остальных пользователей. Для каждой из этих сущностей разрешения могут быть установлены на чтение, запись или выполнение файла:
Разрешения 0644 (в восьмеричной форме) интерпретировались бы как чтение/запись для владельца и только чтение для группы и остальных пользователей. Старшие биты также могут использоваться для указания типа файла (обычный, каталог, канал, сокет и т. д.) и различных других специальных функций. Если разрешения относятся к каталогу, смысл бита выполнения изменяется; при установке бита выполнение каталог может быть просмотрен.
В операционных системах, не поддерживающих Posix, может быть только возможность сделать файл только для чтения или чтения/записи. В этом случае оставшиеся биты разрешений будут синтезированы, чтобы соответствовать типичным значениям. Например, в Windows NT значения по умолчанию — 0644, что означает чтение/запись для владельца и только чтение для всех остальных. Единственное изменение, которое можно сделать, — это сделать файл только для чтения, что отображается как 0444.
Различные константы для методов в File можно найти в File::Constants.
Константы
- ALT_SEPARATOR
-
альтернативный разделитель, специфичный для платформы
- PATH_SEPARATOR
-
разделитель списка путей
- SEPARATOR
-
разделитель частей каталога в пути
- Separator
-
разделитель частей каталога в пути
Публичные методы класса
VALUE
rb_file_s_absolute_path(int argc, const VALUE *argv)
{
rb_check_arity(argc, 1, 2);
return rb_file_absolute_path(argv[0], argc > 1 ? argv[1] : Qnil);
} Преобразует имя пути в абсолютное имя пути. Относительные пути указываются из текущего рабочего каталога процесса, если только не задано dir_string, в этом случае он будет использоваться в качестве отправной точки. Если заданное имя пути начинается с «~», оно НЕ раскрывается, а рассматривается как обычное имя каталога.
File.absolute_path("~oracle/bin") #=> "<relative_path>/~oracle/bin"
static VALUE
rb_file_s_atime(VALUE klass, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
return stat_atime(&st);
} Возвращает время последнего доступа к указанному файлу в виде объекта Time.
file_name может быть объектом IO.
File.atime("testfile") #=> Wed Apr 09 08:51:48 CDT 2003
static VALUE
rb_file_s_basename(int argc, VALUE *argv)
{
VALUE fname, fext, basename;
const char *name, *p;
long f, n;
rb_encoding *enc;
fext = Qnil;
if (rb_check_arity(argc, 1, 2) == 2) {
fext = argv[1];
StringValue(fext);
enc = check_path_encoding(fext);
}
fname = argv[0];
FilePathStringValue(fname);
if (NIL_P(fext) || !(enc = rb_enc_compatible(fname, fext))) {
enc = rb_enc_get(fname);
fext = Qnil;
}
if ((n = RSTRING_LEN(fname)) == 0 || !*(name = RSTRING_PTR(fname)))
return rb_str_new_shared(fname);
p = ruby_enc_find_basename(name, &f, &n, enc);
if (n >= 0) {
if (NIL_P(fext)) {
f = n;
}
else {
const char *fp;
fp = StringValueCStr(fext);
if (!(f = rmext(p, f, n, fp, RSTRING_LEN(fext), enc))) {
f = n;
}
RB_GC_GUARD(fext);
}
if (f == RSTRING_LEN(fname)) return rb_str_new_shared(fname);
}
basename = rb_str_new(p, f);
rb_enc_copy(basename, fname);
OBJ_INFECT(basename, fname);
return basename;
} Возвращает последний компонент указанного в file_name имени файла (после предварительного удаления завершающих разделителей), который может быть сформирован с использованием как File::SEPARATOR, так и File::ALT_SEPARATOR в качестве разделителя, когда File::ALT_SEPARATOR не nil. Если указан suffix и присутствует в конце file_name, он удаляется. Если suffix равен «.*», любое расширение будет удалено.
File.basename("/home/gumby/work/ruby.rb") #=> "ruby.rb"
File.basename("/home/gumby/work/ruby.rb", ".rb") #=> "ruby"
File.basename("/home/gumby/work/ruby.rb", ".*") #=> "ruby"
static VALUE
rb_file_s_birthtime(VALUE klass, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
return stat_birthtime(&st);
} Возвращает время создания для указанного файла.
file_name может быть объектом IO.
File.birthtime("testfile") #=> Wed Apr 09 08:53:13 CDT 2003
Если платформа не имеет времени создания, возникает исключение NotImplementedError.
static VALUE
rb_file_blockdev_p(VALUE obj, VALUE fname)
{
#ifndef S_ISBLK
# ifdef S_IFBLK
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
# else
# define S_ISBLK(m) (0) /* anytime false */
# endif
#endif
#ifdef S_ISBLK
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISBLK(st.st_mode)) return Qtrue;
#endif
return Qfalse;
} Возвращает true, если указанный файл является блочным устройством.
file_name может быть объектом IO.
static VALUE
rb_file_chardev_p(VALUE obj, VALUE fname)
{
#ifndef S_ISCHR
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISCHR(st.st_mode)) return Qtrue;
return Qfalse;
} Возвращает true, если указанный файл является символьным устройством.
file_name может быть объектом IO.
static VALUE
rb_file_s_chmod(int argc, VALUE *argv)
{
mode_t mode;
apply2args(1);
mode = NUM2MODET(*argv++);
return apply2files(chmod_internal, argc, argv, &mode);
} Изменяет биты разрешений для указанных файлов на битовую маску, представленную mode_int. Фактические эффекты зависят от операционной системы (см. начало этого раздела). В Unix-системах см. chmod(2) для получения подробной информации. Возвращает количество обработанных файлов.
File.chmod(0644, "testfile", "out") #=> 2
static VALUE
rb_file_s_chown(int argc, VALUE *argv)
{
struct chown_args arg;
apply2args(2);
arg.owner = to_uid(*argv++);
arg.group = to_gid(*argv++);
return apply2files(chown_internal, argc, argv, &arg);
} Изменяет владельца и группу указанных файлов на указанные числовые идентификаторы владельца и группы. Только процесс с правами суперпользователя может изменить владельца файла. Текущий владелец файла может изменить группу файла на любую группу, к которой принадлежит владелец. nil или идентификатор владельца или группы -1 игнорируется. Возвращает количество обработанных файлов.
File.chown(nil, 100, "testfile")
static VALUE
rb_file_s_ctime(VALUE klass, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
return stat_ctime(&st);
} Возвращает время изменения для указанного файла (время, когда изменялась информация о каталоге файла, а не сам файл).
file_name может быть объектом IO.
Обратите внимание, что в Windows (NTFS) возвращается время создания (время рождения).
File.ctime("testfile") #=> Wed Apr 09 08:53:13 CDT 2003
static VALUE
rb_file_s_unlink(int argc, VALUE *argv, VALUE klass)
{
return apply2files(unlink_internal, argc, argv, 0);
} Удаляет указанные файлы, возвращая количество имен, переданных в качестве аргументов. Вызывает исключение при любой ошибке. Поскольку базовая реализация основана на системном вызове unlink(2), тип вызываемого исключения зависит от его типа ошибки (см. linux.die.net/man/2/unlink) и имеет вид, например, Errno::ENOENT.
См. также Dir::rmdir.
VALUE
rb_file_directory_p(VALUE obj, VALUE fname)
{
#ifndef S_ISDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISDIR(st.st_mode)) return Qtrue;
return Qfalse;
} Возвращает true, если указанный файл является каталогом или символической ссылкой, указывающей на каталог, и false в противном случае.
file_name может быть объектом IO.
File.directory?(".")
static VALUE
rb_file_s_dirname(VALUE klass, VALUE fname)
{
return rb_file_dirname(fname);
} Возвращает все компоненты имени файла, указанного в file_name, за исключением последнего (после предварительного удаления завершающих разделителей). Имя файла может быть сформировано с использованием как File::SEPARATOR, так и File::ALT_SEPARATOR в качестве разделителя, когда File::ALT_SEPARATOR не nil.
File.dirname("/home/gumby/work/ruby.rb") #=> "/home/gumby/work"
static VALUE
rb_file_zero_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (st.st_size == 0) return Qtrue;
return Qfalse;
} Возвращает true, если указанный файл существует и имеет нулевой размер.
file_name может быть объектом IO.
static VALUE
rb_file_executable_p(VALUE obj, VALUE fname)
{
if (rb_eaccess(fname, X_OK) < 0) return Qfalse;
return Qtrue;
} Возвращает true, если указанный файл доступен для выполнения эффективным идентификатором пользователя и группы этого процесса. См. eaccess(3).
static VALUE
rb_file_executable_real_p(VALUE obj, VALUE fname)
{
if (rb_access(fname, X_OK) < 0) return Qfalse;
return Qtrue;
} Возвращает true, если указанный файл доступен для выполнения реальным идентификатором пользователя и группы этого процесса. См. access(3).
static VALUE
rb_file_exist_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
return Qtrue;
} Возвращает true, если указанный файл существует.
file_name может быть объектом IO.
«Файл существует» означает, что системный вызов stat() или fstat() выполнен успешно.
static VALUE
rb_file_exists_p(VALUE obj, VALUE fname)
{
const char *s = "FileTest#";
if (obj == rb_mFileTest) {
s = "FileTest.";
}
else if (obj == rb_cFile ||
(RB_TYPE_P(obj, T_CLASS) &&
RTEST(rb_class_inherited_p(obj, rb_cFile)))) {
s = "File.";
}
rb_warning("%sexists? is a deprecated name, use %sexist? instead", s, s);
return rb_file_exist_p(obj, fname);
} Устаревший метод. Не использовать.
VALUE
rb_file_s_expand_path(int argc, const VALUE *argv)
{
rb_check_arity(argc, 1, 2);
return rb_file_expand_path(argv[0], argc > 1 ? argv[1] : Qnil);
} Преобразует имя пути в абсолютное имя пути. Относительные пути указываются из текущего рабочего каталога процесса, если только не задано dir_string, в этом случае он будет использоваться в качестве отправной точки. Указанное имя пути может начинаться с «~», что раскрывается в домашний каталог владельца процесса (переменная окружения HOME должна быть установлена правильно). «~user» раскрывается в домашний каталог указанного пользователя.
File.expand_path("~oracle/bin") #=> "/home/oracle/bin"
Простой пример использования dir_string показан ниже.
File.expand_path("ruby", "/usr/bin") #=> "/usr/bin/ruby"
Более сложный пример, который также разрешает родительский каталог, показан ниже. Предположим, мы находимся в bin/mygem и хотим получить абсолютный путь lib/mygem.rb.
File.expand_path("../../lib/mygem.rb", __FILE__)
#=> ".../path/to/project/lib/mygem.rb"
Сначала он разрешает родительский элемент __FILE__, то есть bin/, затем переходит к родителю, корню проекта, и добавляет lib/mygem.rb.
static VALUE
rb_file_s_extname(VALUE klass, VALUE fname)
{
const char *name, *e;
long len;
VALUE extname;
FilePathStringValue(fname);
name = StringValueCStr(fname);
len = RSTRING_LEN(fname);
e = ruby_enc_find_extname(name, &len, rb_enc_get(fname));
if (len <= 1)
return rb_str_new(0, 0);
extname = rb_str_subseq(fname, e - name, len); /* keep the dot, too! */
OBJ_INFECT(extname, fname);
return extname;
} Возвращает расширение (часть имени файла в path, начиная с последней точки).
Если path является файлом с точкой или начинается с точки, то начальная точка не рассматривается как начало расширения.
Также возвращается пустая строка, если точка является последним символом в path.
File.extname("test.rb") #=> ".rb"
File.extname("a/b/d/test.rb") #=> ".rb"
File.extname(".a/b/d/test.rb") #=> ".rb"
File.extname("foo.") #=> ""
File.extname("test") #=> ""
File.extname(".profile") #=> ""
File.extname(".profile.sh") #=> ".sh"
static VALUE
rb_file_file_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISREG(st.st_mode)) return Qtrue;
return Qfalse;
} Возвращает true, если указанный file существует и является обычным файлом.
file может быть объектом IO.
Если аргумент file является символической ссылкой, то ссылка будет разрешена, и будет использован файл, на который указывает ссылка.
static VALUE
file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
{
VALUE pattern, path;
VALUE rflags;
int flags;
if (rb_scan_args(argc, argv, "21", &pattern, &path, &rflags) == 3)
flags = NUM2INT(rflags);
else
flags = 0;
StringValue(pattern);
FilePathStringValue(path);
if (flags & FNM_EXTGLOB) {
struct brace_args args;
args.value = path;
args.flags = flags;
if (ruby_brace_expand(RSTRING_PTR(pattern), flags, fnmatch_brace,
(VALUE)&args, rb_enc_get(pattern), pattern) > 0)
return Qtrue;
}
else {
rb_encoding *enc = rb_enc_compatible(pattern, path);
if (!enc) return Qfalse;
if (fnmatch(RSTRING_PTR(pattern), enc, RSTRING_PTR(path), flags) == 0)
return Qtrue;
}
RB_GC_GUARD(pattern);
return Qfalse;
} Возвращает true, если path соответствует pattern. Шаблон не является регулярным выражением; вместо этого он следует правилам, похожим на оболочковые подстановки имён файлов. Он может содержать следующие метасимволы:
-
* -
Соответствует любому файлу. Может быть ограничен другими значениями в подстановке. Эквивалентно
/ .* /xв регулярных выражениях.-
* -
Соответствует всем обычным файлам.
-
c* -
Соответствует всем файлам, начинающимся с
c. -
*c -
Соответствует всем файлам, заканчивающимся на
c. -
*c* -
Соответствует всем файлам, содержащим
c(включая начало и конец).
Для сопоставления скрытых файлов (начинающихся с
.установите флаг File::FNM_DOTMATCH. -
-
** -
Соответствует каталогам рекурсивно или файлам расширительно.
-
? -
Соответствует одному символу. Эквивалентно
/.{1}/в регулярных выражениях. -
[set] -
Соответствует любому символу из
set. Ведёт себя точно так же, как наборы символов вRegexp, включая отрицание наборов ([^a-z]). -
\ -
Экранирует следующий метасимвол.
-
{a,b} -
Соответствует шаблону a и шаблону b, если включен флаг File::FNM_EXTGLOB. Ведёт себя как объединение в
Regexp((?:a|b)).
flags — это побитовое ИЛИ констант FNM_XXX. Тот же шаблон подстановки и флаги используются в Dir::glob.
Примеры:
File.fnmatch('cat', 'cat') #=> true # match entire string
File.fnmatch('cat', 'category') #=> false # only match partial string
File.fnmatch('c{at,ub}s', 'cats') #=> false # { } isn't supported by default
File.fnmatch('c{at,ub}s', 'cats', File::FNM_EXTGLOB) #=> true # { } is supported on FNM_EXTGLOB
File.fnmatch('c?t', 'cat') #=> true # '?' match only 1 character
File.fnmatch('c??t', 'cat') #=> false # ditto
File.fnmatch('c*', 'cats') #=> true # '*' match 0 or more characters
File.fnmatch('c*t', 'c/a/b/t') #=> true # ditto
File.fnmatch('ca[a-z]', 'cat') #=> true # inclusive bracket expression
File.fnmatch('ca[^t]', 'cat') #=> false # exclusive bracket expression ('^' or '!')
File.fnmatch('cat', 'CAT') #=> false # case sensitive
File.fnmatch('cat', 'CAT', File::FNM_CASEFOLD) #=> true # case insensitive
File.fnmatch('?', '/', File::FNM_PATHNAME) #=> false # wildcard doesn't match '/' on FNM_PATHNAME
File.fnmatch('*', '/', File::FNM_PATHNAME) #=> false # ditto
File.fnmatch('[/]', '/', File::FNM_PATHNAME) #=> false # ditto
File.fnmatch('\?', '?') #=> true # escaped wildcard becomes ordinary
File.fnmatch('\a', 'a') #=> true # escaped ordinary remains ordinary
File.fnmatch('\a', '\a', File::FNM_NOESCAPE) #=> true # FNM_NOESCAPE makes '\' ordinary
File.fnmatch('[\?]', '?') #=> true # can escape inside bracket expression
File.fnmatch('*', '.profile') #=> false # wildcard doesn't match leading
File.fnmatch('*', '.profile', File::FNM_DOTMATCH) #=> true # period by default.
File.fnmatch('.*', '.profile') #=> true
rbfiles = '**' '/' '*.rb' # you don't have to do like this. just write in single string.
File.fnmatch(rbfiles, 'main.rb') #=> false
File.fnmatch(rbfiles, './main.rb') #=> false
File.fnmatch(rbfiles, 'lib/song.rb') #=> true
File.fnmatch('**.rb', 'main.rb') #=> true
File.fnmatch('**.rb', './main.rb') #=> false
File.fnmatch('**.rb', 'lib/song.rb') #=> true
File.fnmatch('*', 'dave/.profile') #=> true
pattern = '*' '/' '*'
File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME) #=> false
File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true
pattern = '**' '/' 'foo'
File.fnmatch(pattern, 'a/b/c/foo', File::FNM_PATHNAME) #=> true
File.fnmatch(pattern, '/a/b/c/foo', File::FNM_PATHNAME) #=> true
File.fnmatch(pattern, 'c:/a/b/c/foo', File::FNM_PATHNAME) #=> true
File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME) #=> false
File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true
static VALUE
file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
{
VALUE pattern, path;
VALUE rflags;
int flags;
if (rb_scan_args(argc, argv, "21", &pattern, &path, &rflags) == 3)
flags = NUM2INT(rflags);
else
flags = 0;
StringValue(pattern);
FilePathStringValue(path);
if (flags & FNM_EXTGLOB) {
struct brace_args args;
args.value = path;
args.flags = flags;
if (ruby_brace_expand(RSTRING_PTR(pattern), flags, fnmatch_brace,
(VALUE)&args, rb_enc_get(pattern), pattern) > 0)
return Qtrue;
}
else {
rb_encoding *enc = rb_enc_compatible(pattern, path);
if (!enc) return Qfalse;
if (fnmatch(RSTRING_PTR(pattern), enc, RSTRING_PTR(path), flags) == 0)
return Qtrue;
}
RB_GC_GUARD(pattern);
return Qfalse;
} Возвращает true, если path соответствует pattern. Шаблон не является регулярным выражением; вместо этого он следует правилам, похожим на оболочковые подстановки имён файлов. Он может содержать следующие метасимволы:
-
* -
Соответствует любому файлу. Может быть ограничен другими значениями в подстановке. Эквивалентно
/ .* /xв регулярных выражениях.-
* -
Соответствует всем обычным файлам.
-
c* -
Соответствует всем файлам, начинающимся с
c. -
*c -
Соответствует всем файлам, заканчивающимся на
c. -
*c* -
Соответствует всем файлам, содержащим
c(включая начало и конец).
Для сопоставления скрытых файлов (начинающихся с
.установите флаг File::FNM_DOTMATCH. -
-
** -
Соответствует каталогам рекурсивно или файлам расширительно.
-
? -
Соответствует одному символу. Эквивалентно
/.{1}/в регулярных выражениях. -
[set] -
Соответствует любому символу из
set. Ведёт себя точно так же, как наборы символов вRegexp, включая отрицание наборов ([^a-z]). -
\ -
Экранирует следующий метасимвол.
-
{a,b} -
Соответствует шаблону a и шаблону b, если включен флаг File::FNM_EXTGLOB. Ведёт себя как объединение в
Regexp((?:a|b)).
flags — это побитовое ИЛИ констант FNM_XXX. Тот же шаблон подстановки и флаги используются в Dir::glob.
Примеры:
File.fnmatch('cat', 'cat') #=> true # match entire string
File.fnmatch('cat', 'category') #=> false # only match partial string
File.fnmatch('c{at,ub}s', 'cats') #=> false # { } isn't supported by default
File.fnmatch('c{at,ub}s', 'cats', File::FNM_EXTGLOB) #=> true # { } is supported on FNM_EXTGLOB
File.fnmatch('c?t', 'cat') #=> true # '?' match only 1 character
File.fnmatch('c??t', 'cat') #=> false # ditto
File.fnmatch('c*', 'cats') #=> true # '*' match 0 or more characters
File.fnmatch('c*t', 'c/a/b/t') #=> true # ditto
File.fnmatch('ca[a-z]', 'cat') #=> true # inclusive bracket expression
File.fnmatch('ca[^t]', 'cat') #=> false # exclusive bracket expression ('^' or '!')
File.fnmatch('cat', 'CAT') #=> false # case sensitive
File.fnmatch('cat', 'CAT', File::FNM_CASEFOLD) #=> true # case insensitive
File.fnmatch('?', '/', File::FNM_PATHNAME) #=> false # wildcard doesn't match '/' on FNM_PATHNAME
File.fnmatch('*', '/', File::FNM_PATHNAME) #=> false # ditto
File.fnmatch('[/]', '/', File::FNM_PATHNAME) #=> false # ditto
File.fnmatch('\?', '?') #=> true # escaped wildcard becomes ordinary
File.fnmatch('\a', 'a') #=> true # escaped ordinary remains ordinary
File.fnmatch('\a', '\a', File::FNM_NOESCAPE) #=> true # FNM_NOESCAPE makes '\' ordinary
File.fnmatch('[\?]', '?') #=> true # can escape inside bracket expression
File.fnmatch('*', '.profile') #=> false # wildcard doesn't match leading
File.fnmatch('*', '.profile', File::FNM_DOTMATCH) #=> true # period by default.
File.fnmatch('.*', '.profile') #=> true
rbfiles = '**' '/' '*.rb' # you don't have to do like this. just write in single string.
File.fnmatch(rbfiles, 'main.rb') #=> false
File.fnmatch(rbfiles, './main.rb') #=> false
File.fnmatch(rbfiles, 'lib/song.rb') #=> true
File.fnmatch('**.rb', 'main.rb') #=> true
File.fnmatch('**.rb', './main.rb') #=> false
File.fnmatch('**.rb', 'lib/song.rb') #=> true
File.fnmatch('*', 'dave/.profile') #=> true
pattern = '*' '/' '*'
File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME) #=> false
File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true
pattern = '**' '/' 'foo'
File.fnmatch(pattern, 'a/b/c/foo', File::FNM_PATHNAME) #=> true
File.fnmatch(pattern, '/a/b/c/foo', File::FNM_PATHNAME) #=> true
File.fnmatch(pattern, 'c:/a/b/c/foo', File::FNM_PATHNAME) #=> true
File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME) #=> false
File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true
static VALUE
rb_file_s_ftype(VALUE klass, VALUE fname)
{
struct stat st;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
if (lstat_without_gvl(StringValueCStr(fname), &st) == -1) {
rb_sys_fail_path(fname);
}
return rb_file_ftype(&st);
} Определяет тип указанного файла; возвращаемая строка — одна из “file'', “directory'', “characterSpecial'', “blockSpecial'', “fifo'', “link'', “socket'', или “unknown''.
File.ftype("testfile") #=> "file"
File.ftype("/dev/tty") #=> "characterSpecial"
File.ftype("/tmp/.X11-unix/X0") #=> "socket"
static VALUE
rb_file_grpowned_p(VALUE obj, VALUE fname)
{
#ifndef _WIN32
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (rb_group_member(st.st_gid)) return Qtrue;
#endif
return Qfalse;
} Возвращает true , если указанный файл существует, и эффективная группа идентификаторов вызывающего процесса — владелец файла. Возвращает false в Windows.
file_name может быть объектом IO.
static VALUE
rb_file_identical_p(VALUE obj, VALUE fname1, VALUE fname2)
{
#ifndef _WIN32
struct stat st1, st2;
if (rb_stat(fname1, &st1) < 0) return Qfalse;
if (rb_stat(fname2, &st2) < 0) return Qfalse;
if (st1.st_dev != st2.st_dev) return Qfalse;
if (st1.st_ino != st2.st_ino) return Qfalse;
return Qtrue;
#else
extern VALUE rb_w32_file_identical_p(VALUE, VALUE);
return rb_w32_file_identical_p(fname1, fname2);
#endif
} Возвращает true , если указанные файлы идентичны.
file_1 и file_2 могут быть объектами IO.
open("a", "w") {}
p File.identical?("a", "a") #=> true
p File.identical?("a", "./a") #=> true
File.link("a", "b")
p File.identical?("a", "b") #=> true
File.symlink("a", "c")
p File.identical?("a", "c") #=> true
open("d", "w") {}
p File.identical?("a", "d") #=> false
static VALUE
rb_file_s_join(VALUE klass, VALUE args)
{
return rb_file_join(args);
} Возвращает новую строку, образованную путём объединения строк с использованием "/".
File.join("usr", "mail", "gumby") #=> "usr/mail/gumby"
static VALUE
rb_file_s_lchmod(int argc, VALUE *argv)
{
mode_t mode;
apply2args(1);
mode = NUM2MODET(*argv++);
return apply2files(lchmod_internal, argc, argv, &mode);
} Эквивалентно File::chmod, но не следует за символическими ссылками (поэтому изменит разрешения, связанные со ссылкой, а не с файлом, на который она указывает). Часто недоступно.
static VALUE
rb_file_s_lchown(int argc, VALUE *argv)
{
struct chown_args arg;
apply2args(2);
arg.owner = to_uid(*argv++);
arg.group = to_gid(*argv++);
return apply2files(lchown_internal, argc, argv, &arg);
} Эквивалентно File::chown, но не следует за символическими ссылками (поэтому изменит владельца, связанного со ссылкой, а не с файлом, на который она указывает). Часто недоступно. Возвращает количество файлов в списке аргументов.
static VALUE
rb_file_s_link(VALUE klass, VALUE from, VALUE to)
{
FilePathValue(from);
FilePathValue(to);
from = rb_str_encode_ospath(from);
to = rb_str_encode_ospath(to);
if (link(StringValueCStr(from), StringValueCStr(to)) < 0) {
sys_fail2(from, to);
}
return INT2FIX(0);
} Создаёт новое имя для существующего файла с помощью жёсткой ссылки. Не будет перезаписывать new_name, если оно уже существует (вызовет подкласс SystemCallError). Недоступно на всех платформах.
File.link("testfile", ".testfile") #=> 0
IO.readlines(".testfile")[0] #=> "This is line one\n"
static VALUE
rb_file_s_lstat(VALUE klass, VALUE fname)
{
#ifdef HAVE_LSTAT
struct stat st;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
if (lstat_without_gvl(StringValueCStr(fname), &st) == -1) {
rb_sys_fail_path(fname);
}
return rb_stat_new(&st);
#else
return rb_file_s_stat(klass, fname);
#endif
} Аналогично File::stat, но не следует за последней символической ссылкой. Вместо этого сообщает о самой ссылке.
File.symlink("testfile", "link2test") #=> 0
File.stat("testfile").size #=> 66
File.lstat("link2test").size #=> 8
File.stat("link2test").size #=> 66
static VALUE
rb_file_s_lutime(int argc, VALUE *argv)
{
return utime_internal_i(argc, argv, TRUE);
} Устанавливает время доступа и изменения каждого указанного файла на первые два аргумента. Если файл является символической ссылкой, этот метод действует на саму ссылку, а не на файл, на который она указывает; для обратного поведения см. File.utime. Возвращает количество имён файлов в списке аргументов.
static VALUE
rb_file_s_mkfifo(int argc, VALUE *argv)
{
VALUE path;
struct mkfifo_arg ma;
ma.mode = 0666;
rb_check_arity(argc, 1, 2);
if (argc > 1) {
ma.mode = NUM2MODET(argv[1]);
}
path = argv[0];
FilePathValue(path);
path = rb_str_encode_ospath(path);
ma.path = RSTRING_PTR(path);
if (rb_thread_call_without_gvl(nogvl_mkfifo, &ma, RUBY_UBF_IO, 0)) {
rb_sys_fail_path(path);
}
return INT2FIX(0);
} Создаёт специальный файл FIFO с именем file_name. mode задаёт права доступа к FIFO. Он изменяется umask процесса обычным способом: права доступа создаваемого файла равны (mode & ~umask).
static VALUE
rb_file_s_mtime(VALUE klass, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
return stat_mtime(&st);
} Возвращает время последнего изменения для указанного файла в виде объекта Time.
file_name может быть объектом IO.
File.mtime("testfile") #=> Tue Apr 08 12:58:04 CDT 2003
static VALUE
rb_file_initialize(int argc, VALUE *argv, VALUE io)
{
if (RFILE(io)->fptr) {
rb_raise(rb_eRuntimeError, "reinitializing File");
}
if (0 < argc && argc < 3) {
VALUE fd = rb_check_to_int(argv[0]);
if (!NIL_P(fd)) {
argv[0] = fd;
return rb_io_initialize(argc, argv, io);
}
}
rb_open_file(argc, argv, io);
return io;
} Открывает файл с именем filename в соответствии с заданным mode и возвращает новый объект File.
См. IO.new для описания mode и opt.
Если файл создаётся, биты прав доступа могут быть заданы в perm. Эти биты режима и прав доступа зависят от платформы; в Unix-системах, см. страницы руководства open(2) и chmod(2) для получения подробной информации.
Новый объект File находится в буферизованном режиме (или режиме без синхронизации), если только filename не является tty. См. IO#flush, IO#fsync, IO#fdatasync и IO#sync= о режиме синхронизации.
Примеры
f = File.new("testfile", "r")
f = File.new("newfile", "w+")
f = File.new("newfile", File::CREAT|File::TRUNC|File::RDWR, 0644)
static VALUE
rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
VALUE io = rb_class_new_instance(argc, argv, klass);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
}
return io;
} Без связанного блока, File.open является синонимом для File.new. Если указан необязательный блок кода, ему будет передан открытый file в качестве аргумента, и объект File будет автоматически закрыт по завершении блока. Значение блока будет возвращено из File.open.
Если файл создаётся, его начальные права доступа могут быть установлены с помощью параметра perm. См. File.new для дальнейшего обсуждения.
См. IO.new для описания параметров mode и opt.
static VALUE
rb_file_owned_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (st.st_uid == geteuid()) return Qtrue;
return Qfalse;
} Возвращает true, если указанный файл существует и эффективный идентификатор пользователя вызывающего процесса является владельцем файла.
file_name может быть объектом IO.
static VALUE
rb_file_s_path(VALUE klass, VALUE fname)
{
return rb_get_path(fname);
} Возвращает строковое представление пути
File.path("/dev/null") #=> "/dev/null"
File.path(Pathname.new("/tmp")) #=> "/tmp"
static VALUE
rb_file_pipe_p(VALUE obj, VALUE fname)
{
#ifdef S_IFIFO
# ifndef S_ISFIFO
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
# endif
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISFIFO(st.st_mode)) return Qtrue;
#endif
return Qfalse;
} Возвращает true, если указанный файл является каналом.
file_name может быть объектом IO.
static VALUE
rb_file_readable_p(VALUE obj, VALUE fname)
{
if (rb_eaccess(fname, R_OK) < 0) return Qfalse;
return Qtrue;
} Возвращает true, если указанный файл доступен для чтения эффективным идентификатором пользователя и группы этого процесса. См. eaccess(3).
static VALUE
rb_file_readable_real_p(VALUE obj, VALUE fname)
{
if (rb_access(fname, R_OK) < 0) return Qfalse;
return Qtrue;
} Возвращает true, если указанный файл доступен для чтения реальным идентификатором пользователя и группы этого процесса. См. access(3).
static VALUE
rb_file_s_readlink(VALUE klass, VALUE path)
{
return rb_readlink(path, rb_filesystem_encoding());
} Возвращает имя файла, на который указывает данная ссылка. Недоступно на всех платформах.
File.symlink("testfile", "link2test") #=> 0
File.readlink("link2test") #=> "testfile"
static VALUE
rb_file_s_realdirpath(int argc, VALUE *argv, VALUE klass)
{
VALUE basedir = (rb_check_arity(argc, 1, 2) > 1) ? argv[1] : Qnil;
VALUE path = argv[0];
FilePathValue(path);
return rb_realpath_internal(basedir, path, 0);
} Возвращает реальный (абсолютный) путь к pathname в фактической файловой системе. Реальный путь не содержит символических ссылок или бесполезных точек.
Если указан dir_string, он используется в качестве базового каталога для интерпретации относительного пути вместо текущего каталога.
Последний компонент реального пути может отсутствовать.
static VALUE
rb_file_s_realpath(int argc, VALUE *argv, VALUE klass)
{
VALUE basedir = (rb_check_arity(argc, 1, 2) > 1) ? argv[1] : Qnil;
VALUE path = argv[0];
FilePathValue(path);
return rb_realpath_internal(basedir, path, 1);
} Возвращает реальный (абсолютный) путь к pathname в фактической файловой системе, не содержащий символических ссылок или бесполезных точек.
Если указан dir_string, он используется в качестве базового каталога для интерпретации относительного пути вместо текущего каталога.
Все компоненты пути должны существовать при вызове этого метода.
static VALUE
rb_file_s_rename(VALUE klass, VALUE from, VALUE to)
{
struct rename_args ra;
VALUE f, t;
FilePathValue(from);
FilePathValue(to);
f = rb_str_encode_ospath(from);
t = rb_str_encode_ospath(to);
ra.src = StringValueCStr(f);
ra.dst = StringValueCStr(t);
#if defined __CYGWIN__
errno = 0;
#endif
if ((int)(VALUE)rb_thread_call_without_gvl(no_gvl_rename, &ra,
RUBY_UBF_IO, 0) < 0) {
int e = errno;
#if defined DOSISH
switch (e) {
case EEXIST:
if (chmod(ra.dst, 0666) == 0 &&
unlink(ra.dst) == 0 &&
rename(ra.src, ra.dst) == 0)
return INT2FIX(0);
}
#endif
syserr_fail2(e, from, to);
}
return INT2FIX(0);
} Переименовывает указанный файл в новое имя. Вызывает SystemCallError, если файл не может быть переименован.
File.rename("afile", "afile.bak") #=> 0
static VALUE
rb_file_sgid_p(VALUE obj, VALUE fname)
{
#ifdef S_ISGID
return check3rdbyte(fname, S_ISGID);
#else
return Qfalse;
#endif
} Возвращает true, если у указанного файла установлен бит setgid.
file_name может быть объектом IO.
static VALUE
rb_file_suid_p(VALUE obj, VALUE fname)
{
#ifdef S_ISUID
return check3rdbyte(fname, S_ISUID);
#else
return Qfalse;
#endif
} Возвращает true, если у указанного файла установлен бит setuid.
file_name может быть объектом IO.
static VALUE
rb_file_s_size(VALUE klass, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
return OFFT2NUM(st.st_size);
} Возвращает размер file_name.
file_name может быть объектом IO.
static VALUE
rb_file_size_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qnil;
if (st.st_size == 0) return Qnil;
return OFFT2NUM(st.st_size);
} Возвращает nil, если file_name не существует или имеет нулевой размер, размер файла в противном случае.
file_name может быть объектом IO.
static VALUE
rb_file_socket_p(VALUE obj, VALUE fname)
{
#ifndef S_ISSOCK
# ifdef _S_ISSOCK
# define S_ISSOCK(m) _S_ISSOCK(m)
# else
# ifdef _S_IFSOCK
# define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
# else
# ifdef S_IFSOCK
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
# endif
# endif
# endif
#endif
#ifdef S_ISSOCK
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISSOCK(st.st_mode)) return Qtrue;
#endif
return Qfalse;
} Возвращает true, если указанный файл является сокетом.
file_name может быть объектом IO.
static VALUE
rb_file_s_split(VALUE klass, VALUE path)
{
FilePathStringValue(path); /* get rid of converting twice */
return rb_assoc_new(rb_file_dirname(path), rb_file_s_basename(1,&path));
} Разделяет заданную строку на две части: директорию и имя файла, возвращая их в массиве из двух элементов. См. также File::dirname и File::basename.
File.split("/home/gumby/.profile") #=> ["/home/gumby", ".profile"]
static VALUE
rb_file_s_stat(VALUE klass, VALUE fname)
{
struct stat st;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
if (stat_without_gvl(RSTRING_PTR(fname), &st) < 0) {
rb_sys_fail_path(fname);
}
return rb_stat_new(&st);
} Возвращает объект File::Stat для указанного файла (см. File::Stat).
File.stat("testfile").mtime #=> Tue Apr 08 12:58:04 CDT 2003
static VALUE
rb_file_sticky_p(VALUE obj, VALUE fname)
{
#ifdef S_ISVTX
return check3rdbyte(fname, S_ISVTX);
#else
return Qnil;
#endif
} Возвращает true, если для указанного файла установлен бито sticky.
file_name может быть объектом IO.
static VALUE
rb_file_s_symlink(VALUE klass, VALUE from, VALUE to)
{
FilePathValue(from);
FilePathValue(to);
from = rb_str_encode_ospath(from);
to = rb_str_encode_ospath(to);
if (symlink(StringValueCStr(from), StringValueCStr(to)) < 0) {
sys_fail2(from, to);
}
return INT2FIX(0);
} Создаёт символическую ссылку под именем new_name на существующий файл old_name. Вызывает исключение NotImplemented на платформах, не поддерживающих символические ссылки.
File.symlink("testfile", "link2test") #=> 0
static VALUE
rb_file_symlink_p(VALUE obj, VALUE fname)
{
#ifndef S_ISLNK
# ifdef _S_ISLNK
# define S_ISLNK(m) _S_ISLNK(m)
# else
# ifdef _S_IFLNK
# define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK)
# else
# ifdef S_IFLNK
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
# endif
# endif
# endif
#endif
#ifdef S_ISLNK
struct stat st;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
if (lstat_without_gvl(StringValueCStr(fname), &st) < 0) return Qfalse;
if (S_ISLNK(st.st_mode)) return Qtrue;
#endif
return Qfalse;
} Возвращает true, если указанный файл является символической ссылкой.
static VALUE
rb_file_s_truncate(VALUE klass, VALUE path, VALUE len)
{
struct truncate_arg ta;
int r;
ta.pos = NUM2POS(len);
FilePathValue(path);
path = rb_str_encode_ospath(path);
ta.path = StringValueCStr(path);
r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_truncate, &ta,
RUBY_UBF_IO, NULL);
if (r < 0)
rb_sys_fail_path(path);
return INT2FIX(0);
#undef NUM2POS
} Усекает файл file_name до размера, не превышающего целое число байт. Недоступно на всех платформах.
f = File.new("out", "w")
f.write("1234567890") #=> 10
f.close #=> nil
File.truncate("out", 5) #=> 0
File.size("out") #=> 5
static VALUE
rb_file_s_umask(int argc, VALUE *argv)
{
mode_t omask = 0;
if (argc == 0) {
omask = umask(0);
umask(omask);
}
else if (argc == 1) {
omask = umask(NUM2MODET(argv[0]));
}
else {
rb_check_arity(argc, 0, 1);
}
return MODET2NUM(omask);
} Возвращает текущее значение umask для данного процесса. Если необязательный аргумент указан, устанавливает umask на это значение и возвращает предыдущее значение. Значения umask вычитаются из стандартных разрешений, поэтому umask 0222 сделает файл доступным только для чтения для всех.
File.umask(0006) #=> 18 File.umask #=> 6
static VALUE
rb_file_s_unlink(int argc, VALUE *argv, VALUE klass)
{
return apply2files(unlink_internal, argc, argv, 0);
} Удаляет указанные файлы, возвращая количество переданных имён. При ошибке вызывает исключение. Так как реализация основана на системном вызове unlink(2), тип исключения зависит от типа ошибки (см. linux.die.net/man/2/unlink) и имеет вид, например, Errno::ENOENT.
См. также Dir::rmdir.
static VALUE
rb_file_s_utime(int argc, VALUE *argv)
{
return utime_internal_i(argc, argv, FALSE);
} Устанавливает время доступа и изменения каждого указанного файла на значения первых двух аргументов. Если файл является символической ссылкой, этот метод действует на целевой объект, а не на ссылку; для обратного поведения см. File.lutime. Возвращает количество имён файлов в списке аргументов.
static VALUE
rb_file_world_readable_p(VALUE obj, VALUE fname)
{
#ifdef S_IROTH
struct stat st;
if (rb_stat(fname, &st) < 0) return Qnil;
if ((st.st_mode & (S_IROTH)) == S_IROTH) {
return UINT2NUM(st.st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
}
#endif
return Qnil;
} Если file_name доступен для других, возвращает целое число, представляющее биты разрешений файла file_name. В противном случае возвращает nil. Значение битов зависит от платформы; на Unix-системах см. stat(2).
file_name может быть объектом IO.
File.world_readable?("/etc/passwd") #=> 420
m = File.world_readable?("/etc/passwd")
sprintf("%o", m) #=> "644"
static VALUE
rb_file_world_writable_p(VALUE obj, VALUE fname)
{
#ifdef S_IWOTH
struct stat st;
if (rb_stat(fname, &st) < 0) return Qnil;
if ((st.st_mode & (S_IWOTH)) == S_IWOTH) {
return UINT2NUM(st.st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
}
#endif
return Qnil;
} Если file_name доступен для записи другим, возвращает целое число, представляющее биты разрешений файла file_name. В противном случае возвращает nil. Значение битов зависит от платформы; на Unix-системах см. stat(2).
file_name может быть объектом IO.
File.world_writable?("/tmp") #=> 511
m = File.world_writable?("/tmp")
sprintf("%o", m) #=> "777"
static VALUE
rb_file_writable_p(VALUE obj, VALUE fname)
{
if (rb_eaccess(fname, W_OK) < 0) return Qfalse;
return Qtrue;
} Возвращает true если указанный файл доступен для записи для эффективного пользователя и группы этого процесса. См. eaccess(3).
static VALUE
rb_file_writable_real_p(VALUE obj, VALUE fname)
{
if (rb_access(fname, W_OK) < 0) return Qfalse;
return Qtrue;
} Возвращает true если указанный файл доступен для записи для реального пользователя и группы этого процесса. См. access(3).
static VALUE
rb_file_zero_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (st.st_size == 0) return Qtrue;
return Qfalse;
} Возвращает true если указанный файл существует и имеет нулевой размер.
file_name может быть объектом IO.
Методы публичного экземпляра
static VALUE
rb_file_atime(VALUE obj)
{
rb_io_t *fptr;
struct stat st;
GetOpenFile(obj, fptr);
if (fstat(fptr->fd, &st) == -1) {
rb_sys_fail_path(fptr->pathv);
}
return stat_atime(&st);
} Возвращает время последнего доступа (объект Time) для файла file или эпоху, если к file не было доступа.
File.new("testfile").atime #=> Wed Dec 31 18:00:00 CST 1969
static VALUE
rb_file_birthtime(VALUE obj)
{
rb_io_t *fptr;
struct stat st;
GetOpenFile(obj, fptr);
if (fstat(fptr->fd, &st) == -1) {
rb_sys_fail_path(fptr->pathv);
}
return stat_birthtime(&st);
} Возвращает время создания файла file.
File.new("testfile").birthtime #=> Wed Apr 09 08:53:14 CDT 2003
Если платформа не поддерживает время создания, генерируется исключение NotImplementedError.
static VALUE
rb_file_chmod(VALUE obj, VALUE vmode)
{
rb_io_t *fptr;
mode_t mode;
#if !defined HAVE_FCHMOD || !HAVE_FCHMOD
VALUE path;
#endif
mode = NUM2MODET(vmode);
GetOpenFile(obj, fptr);
#ifdef HAVE_FCHMOD
if (fchmod(fptr->fd, mode) == -1) {
if (HAVE_FCHMOD || errno != ENOSYS)
rb_sys_fail_path(fptr->pathv);
}
else {
if (!HAVE_FCHMOD) return INT2FIX(0);
}
#endif
#if !defined HAVE_FCHMOD || !HAVE_FCHMOD
if (NIL_P(fptr->pathv)) return Qnil;
path = rb_str_encode_ospath(fptr->pathv);
if (chmod(RSTRING_PTR(path), mode) == -1)
rb_sys_fail_path(fptr->pathv);
#endif
return INT2FIX(0);
} Изменяет биты разрешений файла file на битовую маску, представленную mode_int. Действительные эффекты зависят от платформы; в системах Unix см. chmod(2) для получения подробной информации. Следует за символическими ссылками. Также см. File#lchmod.
f = File.new("out", "w");
f.chmod(0644) #=> 0
static VALUE
rb_file_chown(VALUE obj, VALUE owner, VALUE group)
{
rb_io_t *fptr;
rb_uid_t o;
rb_gid_t g;
#ifndef HAVE_FCHOWN
VALUE path;
#endif
o = to_uid(owner);
g = to_gid(group);
GetOpenFile(obj, fptr);
#ifndef HAVE_FCHOWN
if (NIL_P(fptr->pathv)) return Qnil;
path = rb_str_encode_ospath(fptr->pathv);
if (chown(RSTRING_PTR(path), o, g) == -1)
rb_sys_fail_path(fptr->pathv);
#else
if (fchown(fptr->fd, o, g) == -1)
rb_sys_fail_path(fptr->pathv);
#endif
return INT2FIX(0);
} Изменяет владельца и группу файла file на указанные числовые идентификаторы владельца и группы. Только процесс с правами суперпользователя может изменить владельца файла. Текущий владелец файла может изменить группу файла на любую группу, к которой принадлежит владелец. Идентификатор владельца или группы nil или -1 игнорируется. Следует за символическими ссылками. См. также File#lchown.
File.new("testfile").chown(502, 1000)
static VALUE
rb_file_ctime(VALUE obj)
{
rb_io_t *fptr;
struct stat st;
GetOpenFile(obj, fptr);
if (fstat(fptr->fd, &st) == -1) {
rb_sys_fail_path(fptr->pathv);
}
return stat_ctime(&st);
} Возвращает время изменения информации о файле file (то есть, время изменения метаданных, а не самого файла).
Обратите внимание, что в Windows (NTFS) возвращается время создания (время рождения).
File.new("testfile").ctime #=> Wed Apr 09 08:53:14 CDT 2003
static VALUE
rb_file_flock(VALUE obj, VALUE operation)
{
rb_io_t *fptr;
int op[2], op1;
struct timeval time;
op[1] = op1 = NUM2INT(operation);
GetOpenFile(obj, fptr);
op[0] = fptr->fd;
if (fptr->mode & FMODE_WRITABLE) {
rb_io_flush_raw(obj, 0);
}
while ((int)rb_thread_io_blocking_region(rb_thread_flock, op, fptr->fd) < 0) {
int e = errno;
switch (e) {
case EAGAIN:
case EACCES:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
if (op1 & LOCK_NB) return Qfalse;
time.tv_sec = 0;
time.tv_usec = 100 * 1000; /* 0.1 sec */
rb_thread_wait_for(time);
rb_io_check_closed(fptr);
continue;
case EINTR:
#if defined(ERESTART)
case ERESTART:
#endif
break;
default:
rb_syserr_fail_path(e, fptr->pathv);
}
}
return INT2FIX(0);
} Блокирует или разблокирует файл в соответствии со значением locking_constant (логическое ИЛИ значений в таблице ниже). Возвращает false, если File::LOCK_NB указано, и операция в противном случае бы заблокировалась. Не доступно на всех платформах.
Константы блокировки (в классе File):
LOCK_EX | Exclusive lock. Only one process may hold an
| exclusive lock for a given file at a time.
----------+------------------------------------------------
LOCK_NB | Don't block when locking. May be combined
| with other lock options using logical or.
----------+------------------------------------------------
LOCK_SH | Shared lock. Multiple processes may each hold a
| shared lock for a given file at the same time.
----------+------------------------------------------------
LOCK_UN | Unlock. Пример:
# update a counter using write lock
# don't use "w" because it truncates the file before lock.
File.open("counter", File::RDWR|File::CREAT, 0644) {|f|
f.flock(File::LOCK_EX)
value = f.read.to_i + 1
f.rewind
f.write("#{value}\n")
f.flush
f.truncate(f.pos)
}
# read the counter using read lock
File.open("counter", "r") {|f|
f.flock(File::LOCK_SH)
p f.read
}
static VALUE
rb_file_lstat(VALUE obj)
{
#ifdef HAVE_LSTAT
rb_io_t *fptr;
struct stat st;
VALUE path;
GetOpenFile(obj, fptr);
if (NIL_P(fptr->pathv)) return Qnil;
path = rb_str_encode_ospath(fptr->pathv);
if (lstat_without_gvl(RSTRING_PTR(path), &st) == -1) {
rb_sys_fail_path(fptr->pathv);
}
return rb_stat_new(&st);
#else
return rb_io_stat(obj);
#endif
} Аналогично IO#stat, но не следует за последней символической ссылкой. Вместо этого, сообщает о самой ссылке.
File.symlink("testfile", "link2test") #=> 0
File.stat("testfile").size #=> 66
f = File.new("link2test")
f.lstat.size #=> 8
f.stat.size #=> 66
static VALUE
rb_file_mtime(VALUE obj)
{
rb_io_t *fptr;
struct stat st;
GetOpenFile(obj, fptr);
if (fstat(fptr->fd, &st) == -1) {
rb_sys_fail_path(fptr->pathv);
}
return stat_mtime(&st);
} Возвращает время изменения файла file.
File.new("testfile").mtime #=> Wed Apr 09 08:53:14 CDT 2003
static VALUE
rb_file_path(VALUE obj)
{
rb_io_t *fptr;
fptr = RFILE(rb_io_taint_check(obj))->fptr;
rb_io_check_initialized(fptr);
if (NIL_P(fptr->pathv)) {
rb_raise(rb_eIOError, "File is unnamed (TMPFILE?)");
}
return rb_obj_taint(rb_str_dup(fptr->pathv));
} Возвращает путь к файлу file в виде строки. Не нормализует имя.
Путь может не указывать на файл, соответствующий file. Например, путь становится пустым, когда файл перемещен или удален.
Этот метод генерирует исключение IOError для файла file, созданного с помощью File::Constants::TMPFILE, потому что у них нет пути.
File.new("testfile").path #=> "testfile"
File.new("/tmp/../tmp/xxx", "w").path #=> "/tmp/../tmp/xxx"
static VALUE
rb_file_size(VALUE obj)
{
rb_io_t *fptr;
struct stat st;
GetOpenFile(obj, fptr);
if (fptr->mode & FMODE_WRITABLE) {
rb_io_flush_raw(obj, 0);
}
if (fstat(fptr->fd, &st) == -1) {
rb_sys_fail_path(fptr->pathv);
}
return OFFT2NUM(st.st_size);
} Возвращает размер файла file в байтах.
File.new("testfile").size #=> 66
static VALUE
rb_file_path(VALUE obj)
{
rb_io_t *fptr;
fptr = RFILE(rb_io_taint_check(obj))->fptr;
rb_io_check_initialized(fptr);
if (NIL_P(fptr->pathv)) {
rb_raise(rb_eIOError, "File is unnamed (TMPFILE?)");
}
return rb_obj_taint(rb_str_dup(fptr->pathv));
} Возвращает путь к файлу file в виде строки. Не нормализует имя.
Путь может не указывать на файл, соответствующий file. Например, путь становится пустым, когда файл перемещен или удален.
Этот метод генерирует исключение IOError для файла file, созданного с помощью File::Constants::TMPFILE, потому что у них нет пути.
File.new("testfile").path #=> "testfile"
File.new("/tmp/../tmp/xxx", "w").path #=> "/tmp/../tmp/xxx"
static VALUE
rb_file_truncate(VALUE obj, VALUE len)
{
rb_io_t *fptr;
struct ftruncate_arg fa;
fa.pos = NUM2POS(len);
GetOpenFile(obj, fptr);
if (!(fptr->mode & FMODE_WRITABLE)) {
rb_raise(rb_eIOError, "not opened for writing");
}
rb_io_flush_raw(obj, 0);
fa.fd = fptr->fd;
if ((int)rb_thread_io_blocking_region(nogvl_ftruncate, &fa, fa.fd) < 0) {
rb_sys_fail_path(fptr->pathv);
}
return INT2FIX(0);
#undef NUM2POS
} Усекает файл file до не более чем целое байт. Файл должен быть открыт для записи. Не доступно на всех платформах.
f = File.new("out", "w")
f.syswrite("1234567890") #=> 10
f.truncate(5) #=> 0
f.close() #=> nil
File.size("out") #=> 5
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.