class File
A File is an abstraction of any file object accessible by the program and is closely associated with class IO. File includes the methods of module FileTest as class methods, allowing you to write (for example) File.exist?("foo").
In the description of File methods, permission bits are a platform-specific set of bits that indicate permissions of a file. On Unix-based systems, permissions are viewed as a set of three octets, for the owner, the group, and the rest of the world. For each of these entities, permissions may be set to read, write, or execute the file:
The permission bits 0644 (in octal) would thus be interpreted as read/write for owner, and read-only for group and other. Higher-order bits may also be used to indicate the type of file (plain, directory, pipe, socket, and so on) and various other special features. If the permissions are for a directory, the meaning of the execute bit changes; when set the directory can be searched.
On non-Posix operating systems, there may be only the ability to make a file read-only or read-write. In this case, the remaining permission bits will be synthesized to resemble typical values. For instance, on Windows NT the default permission bits are 0644, which means read/write for owner, read-only for all others. The only change that can be made is to make the file read-only, which is reported as 0444.
Various constants for the methods in File can be found in File::Constants.
Постоянные значения
- ALT_SEPARATOR
-
альтернативный разделитель (зависит от платформы)
- PATH_SEPARATOR
-
разделитель списка путей
- SEPARATOR
-
разделяет части каталога в пути
- Separator
-
разделяет части каталога в пути
Открытые методы класса
static VALUE
s_absolute_path(int c, const VALUE * v, VALUE _)
{
return rb_file_s_absolute_path(c, v);
} Преобразует имя пути в абсолютное имя пути. Относительные пути указываются из текущего рабочего каталога процесса, если только не указана dir_string, в этом случае она будет использоваться в качестве начальной точки. Если заданное имя пути начинается с “~”, оно НЕ раскрывается, а рассматривается как обычное имя каталога.
File.absolute_path("~oracle/bin") #=> "<relative_path>/~oracle/bin"
static VALUE
s_absolute_path_p(VALUE klass, VALUE fname)
{
VALUE path = rb_get_path(fname);
if (!rb_is_absolute_path(RSTRING_PTR(path))) return Qfalse;
return Qtrue;
} Возвращает true если file_name является абсолютным путем, и false в противном случае.
File.absolute_path?("c:/foo") #=> false (on Linux), true (on Windows)
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 _)
{
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);
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"
RUBY_FUNC_EXPORTED VALUE
rb_file_s_birthtime(VALUE klass, VALUE fname)
{
statx_data st;
if (rb_statx(fname, &st, STATX_BTIME) < 0) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
return statx_birthtime(&st, fname);
} 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, VALUE _)
{
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, VALUE _)
{
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).
Windows не поддерживает разрешения на выполнение отдельно от разрешений на чтение. В Windows файл считается исполняемым, только если он заканчивается на .bat, .cmd, .com или .exe.
Обратите внимание, что некоторые функции безопасности на уровне ОС могут привести к возврату true, даже если файл недоступен для выполнения эффективным пользователем/группой.
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).
Windows не поддерживает разрешения на выполнение отдельно от разрешений на чтение. В Windows файл считается исполняемым, только если он заканчивается на .bat, .cmd, .com или .exe.
Обратите внимание, что некоторые функции безопасности на уровне ОС могут привести к возврату true, даже если файл недоступен для выполнения реальным пользователем/группой.
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);
} Устаревший метод. Не использовать.
static VALUE
s_expand_path(int c, const VALUE * v, VALUE _)
{
return rb_file_s_expand_path(c, v);
} Преобразует имя пути в абсолютный путь. Относительные пути относятся к текущей рабочей директории процесса, если не указано dir_string, в этом случае он будет использоваться в качестве отправной точки. Указанное имя пути может начинаться с «~», которое расширяется до домашнего каталога владельца процесса (переменная среды HOME должна быть установлена правильно). «~пользователь» расширяется до домашнего каталога указанного пользователя.
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! */
return extname;
} Возвращает расширение (часть имени файла в path, начиная с последней точки).
Если path является файлом с точкой или начинается с точки, то начальная точка не учитывается при определении начала расширения.
Также возвращается пустая строка, когда точка является последним символом в path.
В Windows отбрасываются конечные точки.
File.extname("test.rb") #=> ".rb"
File.extname("a/b/d/test.rb") #=> ".rb"
File.extname(".a/b/d/test.rb") #=> ".rb"
File.extname("foo.") #=> "" on Windows
File.extname("foo.") #=> "." on non-Windows
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;
StringValueCStr(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 Значение шаблона не является регулярным выражением; вместо этого оно следует правилам, аналогичным оболочке shell.
-
* -
Совпадает с любым файлом. Может быть ограничен другими значениями в шаблоне. Эквивалентно
/ .* /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('cat', 'CAT', File::FNM_SYSCASE) #=> true or false # depends on the system default
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;
StringValueCStr(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 Значение шаблона не является регулярным выражением; вместо этого оно следует правилам, аналогичным оболочке shell.
-
* -
Совпадает с любым файлом. Может быть ограничен другими значениями в шаблоне. Эквивалентно
/ .* /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('cat', 'CAT', File::FNM_SYSCASE) #=> true or false # depends on the system default
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, VALUE _)
{
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, VALUE _)
{
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, VALUE _)
{
return utime_internal_i(argc, argv, TRUE);
} Устанавливает время доступа и изменения каждого указанного файла на два первых аргумента. Если файл является символической ссылкой, этот метод воздействует на саму ссылку, а не на её референт; для обратного поведения, см. File.utime. Возвращает количество имен файлов в списке аргументов.
static VALUE
rb_file_s_mkfifo(int argc, VALUE *argv, VALUE _)
{
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_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
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).
Обратите внимание, что некоторые функции безопасности на уровне ОС могут привести к возврату true, даже если файл недоступен для чтения эффективным пользователем/группой.
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).
Обратите внимание, что некоторые функции безопасности на уровне ОС могут привести к возврату true, даже если файл недоступен для чтения реальным пользователем/группой.
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 или false, если у указанного файла установлен бит 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 может быть объектом 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 может быть объектом 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 или false, если указанный файл является сокетом.
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,Qundef));
} Разделяет данную строку на составляющие директории и файла и возвращает их в массиве из двух элементов. Также см. 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 или false, если у указанного файла установлен бит 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 или false, если указанный файл является символической ссылкой.
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, VALUE _)
{
mode_t omask = 0;
switch (argc) {
case 0:
omask = umask(0);
umask(omask);
break;
case 1:
omask = umask(NUM2MODET(argv[0]));
break;
default:
rb_error_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, VALUE _)
{
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 или false, если указанный файл доступен для записи эффективному пользователю и группе текущего процесса. См. eaccess(3).
Обратите внимание, что некоторые функции безопасности ОС могут привести к возвращению true, даже если файл недоступен для записи эффективному пользователю/группе.
static VALUE
rb_file_writable_real_p(VALUE obj, VALUE fname)
{
if (rb_access(fname, W_OK) < 0) return Qfalse;
return Qtrue;
} Возвращает true или false, если указанный файл доступен для записи реальному пользователю и группе текущего процесса. См. access(3).
Обратите внимание, что некоторые функции безопасности ОС могут привести к возвращению true, даже если файл недоступен для записи реальному пользователю/группе.
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 или false, если указанный файл существует и имеет нулевой размер.
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.new("testfile").atime #=> Wed Dec 31 18:00:00 CST 1969
static VALUE
rb_file_birthtime(VALUE obj)
{
rb_io_t *fptr;
statx_data st;
GetOpenFile(obj, fptr);
if (fstatx_without_gvl(fptr->fd, &st, STATX_BTIME) == -1) {
rb_sys_fail_path(fptr->pathv);
}
return statx_birthtime(&st, fptr->pathv);
} Возвращает время создания файла.
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);
} Изменяет биты разрешений файла на битовую комбинацию, представленную 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);
} Изменяет владельца и группу файла на заданные числовые идентификаторы владельца и группы. Только процесс с правами суперпользователя может изменить владельца файла. Текущий владелец файла может изменить группу файла на любую группу, к которой принадлежит владелец. 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);
} Возвращает время изменения файла (то есть время изменения информации о каталоге о файле, а не самого файла).
Обратите внимание, что в 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.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_str_dup(fptr->pathv);
} Возвращает путь к файлу, использованному для создания файла, как строку. Не нормализует имя.
Путь может не указывать на файл, соответствующий файлу. Например, путь становится пустым, когда файл был перемещен или удален.
Этот метод генерирует IOError для файла, созданного с помощью 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.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_str_dup(fptr->pathv);
} Возвращает путь к файлу, использованному для создания файла, как строку. Не нормализует имя.
Путь может не указывать на файл, соответствующий файлу. Например, путь становится пустым, когда файл был перемещен или удален.
Этот метод генерирует IOError для файла, созданного с помощью 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
} Усекает файл до максимум целого байтов. Файл должен быть открыт для записи. Недоступно на всех платформах.
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.