класс Dir
Объекты класса Dir являются потоками каталогов, представляющими каталоги в файловой системе. Они предоставляют различные способы перечисления каталогов и их содержимого. См. также File.
Каталог, используемый в этих примерах, содержит две обычные файлы (config.h и main.rb), родительский каталог (..), и сам каталог (.).
Методы публичного класса
static VALUE
dir_s_aref(int argc, VALUE *argv, VALUE obj)
{
VALUE opts, base;
argc = rb_scan_args(argc, argv, "*:", NULL, &opts);
dir_glob_options(opts, &base, NULL);
if (argc == 1) {
return rb_push_glob(argv[0], base, 0);
}
return dir_globs(argc, argv, base, 0);
} Эквивалентно вызову Dir.glob([string,...], 0).
static VALUE
dir_s_chdir(int argc, VALUE *argv, VALUE obj)
{
VALUE path = Qnil;
if (rb_check_arity(argc, 0, 1) == 1) {
path = rb_str_encode_ospath(rb_get_path(argv[0]));
}
else {
const char *dist = getenv("HOME");
if (!dist) {
dist = getenv("LOGDIR");
if (!dist) rb_raise(rb_eArgError, "HOME/LOGDIR not set");
}
path = rb_str_new2(dist);
}
if (chdir_blocking > 0) {
if (!rb_block_given_p() || rb_thread_current() != chdir_thread)
rb_warn("conflicting chdir during another chdir block");
}
if (rb_block_given_p()) {
struct chdir_data args;
args.old_path = rb_str_encode_ospath(rb_dir_getwd());
args.new_path = path;
args.done = FALSE;
return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
}
else {
char *p = RSTRING_PTR(path);
int r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_chdir, p,
RUBY_UBF_IO, 0);
if (r < 0)
rb_sys_fail_path(path);
}
return INT2FIX(0);
} Изменяет текущий рабочий каталог процесса на указанную строку. При вызове без аргумента, меняет каталог на значение переменной окружения HOME, или LOGDIR. SystemCallError (вероятно, Errno::ENOENT) если целевой каталог не существует.
Если задан блок, он получает имя нового текущего каталога, и блок выполняется с этим каталогом в качестве текущего. Исходный рабочий каталог восстанавливается при выходе из блока. Значение возвращаемое chdir — это значение блока. chdir блоки могут быть вложены, но в многопоточной программе будет генерироваться ошибка, если поток попытается открыть chdir блок, в то время как другой поток уже открыл его.
Dir.chdir("/var/spool/mail")
puts Dir.pwd
Dir.chdir("/tmp") do
puts Dir.pwd
Dir.chdir("/usr") do
puts Dir.pwd
end
puts Dir.pwd
end
puts Dir.pwd
выводит:
/var/spool/mail /tmp /usr /tmp /var/spool/mail
static VALUE
dir_s_children(int argc, VALUE *argv, VALUE io)
{
VALUE dir;
dir = dir_open_dir(argc, argv);
return rb_ensure(dir_collect_children, dir, dir_close, dir);
} Возвращает массив, содержащий все имена файлов, кроме «.» и «..» в заданном каталоге. Сгенерирует SystemCallError если указанный каталог не существует.
Необязательный ключевой параметр кодировка задаёт кодировку каталога. Если не указан, используется кодировка файловой системы.
Dir.children("testdir") #=> ["config.h", "main.rb"]
static VALUE
dir_s_chroot(VALUE dir, VALUE path)
{
path = check_dirname(path);
if (chroot(RSTRING_PTR(path)) == -1)
rb_sys_fail_path(path);
return INT2FIX(0);
} Изменяет представление файловой системы корня для текущего процесса. Только привилегированный процесс может выполнить этот вызов. Не доступно на всех платформах. В системах Unix, см. chroot(2) для получения дополнительной информации.
static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
const char *p;
int r;
dir = check_dirname(dir);
p = RSTRING_PTR(dir);
r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_rmdir, (void *)p, RUBY_UBF_IO, 0);
if (r < 0)
rb_sys_fail_path(dir);
return INT2FIX(0);
} Удаляет указанный каталог. Вызывает подкласс SystemCallError если каталог не пуст.
static VALUE
dir_s_each_child(int argc, VALUE *argv, VALUE io)
{
VALUE dir;
RETURN_ENUMERATOR(io, argc, argv);
dir = dir_open_dir(argc, argv);
rb_ensure(dir_each_child, dir, dir_close, dir);
return Qnil;
} Вызывает блок один раз для каждой записи, кроме «.» и «..» в указанном каталоге, передавая имя файла каждой записи в качестве параметра в блок.
Если блок не задан, возвращается перечислитель вместо него.
Dir.each_child("testdir") {|x| puts "Got #{x}" }
выводит:
Got config.h Got main.rb
static VALUE
rb_dir_s_empty_p(VALUE obj, VALUE dirname)
{
VALUE result, orig;
const char *path;
enum {false_on_notdir = 1};
FilePathValue(dirname);
orig = rb_str_dup_frozen(dirname);
dirname = rb_str_encode_ospath(dirname);
dirname = rb_str_dup_frozen(dirname);
path = RSTRING_PTR(dirname);
#if defined HAVE_GETATTRLIST && defined ATTR_DIR_ENTRYCOUNT
{
u_int32_t attrbuf[SIZEUP32(fsobj_tag_t)];
struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_OBJTAG,};
if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), 0) != 0)
rb_sys_fail_path(orig);
if (*(const fsobj_tag_t *)(attrbuf+1) == VT_HFS) {
al.commonattr = 0;
al.dirattr = ATTR_DIR_ENTRYCOUNT;
if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), 0) == 0) {
if (attrbuf[0] >= 2 * sizeof(u_int32_t))
return attrbuf[1] ? Qfalse : Qtrue;
if (false_on_notdir) return Qfalse;
}
rb_sys_fail_path(orig);
}
}
#endif
result = (VALUE)rb_thread_call_without_gvl(nogvl_dir_empty_p, (void *)path,
RUBY_UBF_IO, 0);
if (result == Qundef) {
rb_sys_fail_path(orig);
}
return result;
} Возвращает true если указанный файл является пустым каталогом, false если это не каталог или каталог не пустой.
static VALUE
dir_entries(int argc, VALUE *argv, VALUE io)
{
VALUE dir;
dir = dir_open_dir(argc, argv);
return rb_ensure(dir_collect, dir, dir_close, dir);
} Возвращает массив, содержащий все имена файлов в заданном каталоге. Вызовет SystemCallError если указанный каталог не существует.
Необязательный ключевой параметр кодировка задаёт кодировку каталога. Если не указан, используется кодировка файловой системы.
Dir.entries("testdir") #=> [".", "..", "config.h", "main.rb"]
VALUE
rb_file_directory_p(void)
{
} Возвращает true если указанный файл является каталогом, false в противном случае.
static VALUE
rb_dir_exists_p(VALUE obj, VALUE fname)
{
rb_warning("Dir.exists? is a deprecated name, use Dir.exist? instead");
return rb_file_directory_p(obj, fname);
} Метод устарел. Не используйте.
static VALUE
dir_foreach(int argc, VALUE *argv, VALUE io)
{
VALUE dir;
RETURN_ENUMERATOR(io, argc, argv);
dir = dir_open_dir(argc, argv);
rb_ensure(dir_each, dir, dir_close, dir);
return Qnil;
} Вызывает блок один раз для каждой записи в указанном каталоге, передавая имя файла каждой записи в качестве параметра в блок.
Если блок не задан, возвращается перечислитель вместо него.
Dir.foreach("testdir") {|x| puts "Got #{x}" }
выводит:
Got . Got .. Got config.h Got main.rb
static VALUE
dir_s_getwd(VALUE dir)
{
return rb_dir_getwd();
} Возвращает путь к текущему рабочему каталогу данного процесса в виде строки.
Dir.chdir("/tmp") #=> 0
Dir.getwd #=> "/tmp"
Dir.pwd #=> "/tmp"
static VALUE
dir_s_glob(int argc, VALUE *argv, VALUE obj)
{
VALUE str, rflags, ary, opts, base;
int flags;
argc = rb_scan_args(argc, argv, "11:", &str, &rflags, &opts);
if (argc == 2)
flags = NUM2INT(rflags);
else
flags = 0;
dir_glob_options(opts, &base, &flags);
ary = rb_check_array_type(str);
if (NIL_P(ary)) {
ary = rb_push_glob(str, base, flags);
}
else {
VALUE v = ary;
ary = dir_globs(RARRAY_LEN(v), RARRAY_CONST_PTR(v), base, flags);
RB_GC_GUARD(v);
}
if (rb_block_given_p()) {
rb_ary_each(ary);
return Qnil;
}
return ary;
} Расширяет pattern, что является строкой шаблона или массивом строк шаблонов, и возвращает массив, содержащий соответствующие имена файлов. Если задан блок, вызывает блок один раз для каждого соответствующего имени файла, передавая имя файла в качестве параметра в блок.
Необязательный ключевой параметр base задаёт базовый каталог для интерпретации относительных путей вместо текущего рабочего каталога. Поскольку результаты в этом случае не имеют префикса имени базового каталога, вам нужно будет добавить имя базового каталога, если вы хотите получить реальные пути.
Обратите внимание, что шаблон не является регулярным выражением, он ближе к оболочке glob. См. File::fnmatch для объяснения значения параметра flags. Чувствительность к регистру зависит от вашей системы (File::FNM_CASEFOLD игнорируется), как и порядок возврата результатов.
-
* -
Соответствует любому файлу. Может быть ограничен другими значениями в glob. Эквивалентно
/ .* /mxв регулярных выражениях.-
* -
Соответствует всем файлам
-
c* -
Соответствует всем файлам, начинающимся с
c -
*c -
Соответствует всем файлам, заканчивающимся на
c -
*c* -
Соответствует всем файлам, содержащим
c(включая начало и конец).
Обратите внимание, что это не будет соответствовать скрытым файлам Unix-подобных систем (dotфайлам). Чтобы включить их в результаты поиска, необходимо использовать флаг File::FNM_DOTMATCH или что-то вроде
"{*,.*}". -
-
** -
Рекурсивно соответствует каталогам.
-
? -
Соответствует одному символу. Эквивалентно
/.{1}/в регулярных выражениях. -
[set] -
Соответствует любому символу в
set. Ведёт себя точно так же, как наборы символов вRegexp, включая отрицание наборов ([^a-z]). -
{p,q} -
Соответствует либо литеральному
pили литеральномуq. Эквивалентно чередованию шаблонов в регулярных выражениях.Соответствующие литералы могут быть длиннее одного символа. Может быть указано более двух литералов.
-
\ -
Экранирует следующий метасимвол.
Обратите внимание, что это означает, что вы не можете использовать обратную косую черту в Windows как часть glob, например,
Dir["c:\foo*"]не сработает, используйтеDir["c:/foo*"]вместо этого.
Примеры:
Dir["config.?"] #=> ["config.h"]
Dir.glob("config.?") #=> ["config.h"]
Dir.glob("*.[a-z][a-z]") #=> ["main.rb"]
Dir.glob("*.[^r]*") #=> ["config.h"]
Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"]
Dir.glob("*") #=> ["config.h", "main.rb"]
Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "..", "config.h", "main.rb"]
Dir.glob(["*.rb", "*.h"]) #=> ["main.rb", "config.h"]
rbfiles = File.join("**", "*.rb")
Dir.glob(rbfiles) #=> ["main.rb",
# "lib/song.rb",
# "lib/song/karaoke.rb"]
Dir.glob(rbfiles, base: "lib") #=> ["song.rb",
# "song/karaoke.rb"]
libdirs = File.join("**", "lib")
Dir.glob(libdirs) #=> ["lib"]
librbfiles = File.join("**", "lib", "**", "*.rb")
Dir.glob(librbfiles) #=> ["lib/song.rb",
# "lib/song/karaoke.rb"]
librbfiles = File.join("**", "lib", "*.rb")
Dir.glob(librbfiles) #=> ["lib/song.rb"]
static VALUE
dir_s_home(int argc, VALUE *argv, VALUE obj)
{
VALUE user;
const char *u = 0;
rb_check_arity(argc, 0, 1);
user = (argc > 0) ? argv[0] : Qnil;
if (!NIL_P(user)) {
SafeStringValue(user);
rb_must_asciicompat(user);
u = StringValueCStr(user);
if (*u) {
return rb_home_dir_of(user, rb_str_new(0, 0));
}
}
return rb_default_home_dir(rb_str_new(0, 0));
} Возвращает домашний каталог текущего пользователя или указанного пользователя, если он задан.
static VALUE
dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
{
struct mkdir_arg m;
VALUE path, vmode;
int r;
if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) {
m.mode = NUM2MODET(vmode);
}
else {
m.mode = 0777;
}
path = check_dirname(path);
m.path = RSTRING_PTR(path);
r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_mkdir, &m, RUBY_UBF_IO, 0);
if (r < 0)
rb_sys_fail_path(path);
return INT2FIX(0);
} Создаёт новую папку с именем, указанным в строке, с правами доступа, заданными необязательным параметром целое число. Права доступа могут быть изменены значением File::umask, и игнорируются в NT. Вызывает SystemCallError если папку создать не удалось. Смотрите также обсуждение прав доступа в документации класса для File.
Dir.mkdir(File.join(Dir.home, ".foo"), 0700) #=> 0
# File lib/tmpdir.rb, line 85
def self.mktmpdir(prefix_suffix=nil, *rest)
base = nil
path = Tmpname.create(prefix_suffix || "d", *rest) {|path, _, _, d|
base = d
mkdir(path, 0700)
}
if block_given?
begin
yield path
ensure
unless base
stat = File.stat(File.dirname(path))
if stat.world_writable? and !stat.sticky?
raise ArgumentError, "parent directory is world writable but not sticky"
end
end
FileUtils.remove_entry path
end
else
path
end
end Dir.mktmpdir создаёт временную папку.
Папка создаётся с правами доступа 0700. Приложение не должно изменять права доступа, чтобы сделать временную папку доступной другим пользователям.
Префикс и суффикс имени папки задаются необязательным первым аргументом, prefix_suffix.
-
Если он не указан или равен nil, используется «d» в качестве префикса и нет суффикса.
-
Если это строка, она используется в качестве префикса и нет суффикса.
-
Если это массив, первый элемент используется в качестве префикса, а второй — в качестве суффикса.
Dir.mktmpdir {|dir| dir is ".../d..." }
Dir.mktmpdir("foo") {|dir| dir is ".../foo..." }
Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" }
Папка создаётся в Dir.tmpdir или в необязательном втором аргументе tmpdir, если задано ненулевое значение.
Dir.mktmpdir {|dir| dir is "#{Dir.tmpdir}/d..." }
Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }
Если задан блок, он вызывается с путём к папке. Папка и её содержимое удаляются с помощью FileUtils.remove_entry перед тем, как Dir.mktmpdir вернёт значение. Возвращается значение блока.
Dir.mktmpdir {|dir|
# use the directory...
open("#{dir}/foo", "w") { ... }
} Если блок не задан, возвращается путь к папке. В этом случае Dir.mktmpdir не удаляет папку.
dir = Dir.mktmpdir
begin
# use the directory...
open("#{dir}/foo", "w") { ... }
ensure
# remove the directory.
FileUtils.remove_entry dir
end static VALUE
dir_initialize(int argc, VALUE *argv, VALUE dir)
{
struct dir_data *dp;
rb_encoding *fsenc;
VALUE dirname, opt, orig;
static ID keyword_ids[1];
const char *path;
if (!keyword_ids[0]) {
keyword_ids[0] = rb_id_encoding();
}
fsenc = rb_filesystem_encoding();
rb_scan_args(argc, argv, "1:", &dirname, &opt);
if (!NIL_P(opt)) {
VALUE enc;
rb_get_kwargs(opt, keyword_ids, 0, 1, &enc);
if (enc != Qundef && !NIL_P(enc)) {
fsenc = rb_to_encoding(enc);
}
}
FilePathValue(dirname);
orig = rb_str_dup_frozen(dirname);
dirname = rb_str_encode_ospath(dirname);
dirname = rb_str_dup_frozen(dirname);
TypedData_Get_Struct(dir, struct dir_data, &dir_data_type, dp);
if (dp->dir) closedir(dp->dir);
dp->dir = NULL;
RB_OBJ_WRITE(dir, &dp->path, Qnil);
dp->enc = fsenc;
path = RSTRING_PTR(dirname);
dp->dir = opendir_without_gvl(path);
if (dp->dir == NULL) {
int e = errno;
if (rb_gc_for_fd(e)) {
dp->dir = opendir_without_gvl(path);
}
#ifdef HAVE_GETATTRLIST
else if (e == EIO) {
u_int32_t attrbuf[1];
struct attrlist al = {ATTR_BIT_MAP_COUNT, 0};
if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW) == 0) {
dp->dir = opendir_without_gvl(path);
}
}
#endif
if (dp->dir == NULL) {
RB_GC_GUARD(dirname);
rb_syserr_fail_path(e, orig);
}
}
RB_OBJ_WRITE(dir, &dp->path, orig);
return dir;
} Возвращает новый объект каталога для указанной папки.
Необязательный ключевой аргумент encoding указывает кодировку папки. Если не указано, используется кодировка файловой системы.
static VALUE
dir_s_open(int argc, VALUE *argv, VALUE klass)
{
struct dir_data *dp;
VALUE dir = TypedData_Make_Struct(klass, struct dir_data, &dir_data_type, dp);
dir_initialize(argc, argv, dir);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, dir, dir_close, dir);
}
return dir;
} Необязательный ключевой аргумент encoding указывает кодировку папки. Если не указано, используется кодировка файловой системы.
Без блока open является синонимом Dir::new. Если блок присутствует, ему передаётся aDir в качестве параметра. Каталог закрывается в конце блока, и Dir::open возвращает значение блока.
static VALUE
dir_s_getwd(VALUE dir)
{
return rb_dir_getwd();
} Возвращает путь к текущей рабочей директории этого процесса в виде строки.
Dir.chdir("/tmp") #=> 0
Dir.getwd #=> "/tmp"
Dir.pwd #=> "/tmp"
static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
const char *p;
int r;
dir = check_dirname(dir);
p = RSTRING_PTR(dir);
r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_rmdir, (void *)p, RUBY_UBF_IO, 0);
if (r < 0)
rb_sys_fail_path(dir);
return INT2FIX(0);
} Удаляет указанную папку. Вызывает подкласс SystemCallError если папка не пуста.
# File lib/tmpdir.rb, line 21
def self.tmpdir
if $SAFE > 0
@@systmpdir.dup
else
tmp = nil
[ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], @@systmpdir, '/tmp', '.'].each do |dir|
next if !dir
dir = File.expand_path(dir)
if stat = File.stat(dir) and stat.directory? and stat.writable? and
(!stat.world_writable? or stat.sticky?)
tmp = dir
break
end rescue nil
end
raise ArgumentError, "could not find a temporary directory" unless tmp
tmp
end
end Возвращает путь к временной папке операционной системы.
static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
const char *p;
int r;
dir = check_dirname(dir);
p = RSTRING_PTR(dir);
r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_rmdir, (void *)p, RUBY_UBF_IO, 0);
if (r < 0)
rb_sys_fail_path(dir);
return INT2FIX(0);
} Удаляет указанную папку. Вызывает подкласс SystemCallError если папка не пуста.
Методы публичного экземпляра
static VALUE
dir_collect_children(VALUE dir)
{
VALUE ary = rb_ary_new();
dir_each_entry(dir, rb_ary_push, ary, TRUE);
return ary;
} Возвращает массив, содержащий все имена файлов, кроме «.» и «..» в этом каталоге.
d = Dir.new("testdir")
d.children #=> ["config.h", "main.rb"]
static VALUE
dir_close(VALUE dir)
{
struct dir_data *dirp;
dirp = dir_get(dir);
if (!dirp->dir) return Qnil;
closedir(dirp->dir);
dirp->dir = NULL;
return Qnil;
} Закрывает поток каталога. Вызов этого метода для закрытого объекта Dir игнорируется с Ruby 2.3.
d = Dir.new("testdir")
d.close #=> nil
static VALUE
dir_each(VALUE dir)
{
RETURN_ENUMERATOR(dir, 0, 0);
return dir_each_entry(dir, dir_yield, Qnil, FALSE);
} Вызывает блок один раз для каждой записи в этом каталоге, передавая имя файла каждой записи в качестве параметра блоку.
Если блок не указан, вместо него возвращается перечислитель.
d = Dir.new("testdir")
d.each {|x| puts "Got #{x}" }
выводит:
Got . Got .. Got config.h Got main.rb
static VALUE
dir_each_child_m(VALUE dir)
{
RETURN_ENUMERATOR(dir, 0, 0);
return dir_each_entry(dir, dir_yield, Qnil, TRUE);
} Вызывает блок один раз для каждой записи, кроме «.» и «..» в этом каталоге, передавая имя файла каждой записи в качестве параметра блоку.
Если блок не указан, вместо него возвращается перечислитель.
d = Dir.new("testdir")
d.each_child {|x| puts "Got #{x}" }
выводит:
Got config.h Got main.rb
static VALUE
dir_fileno(VALUE dir)
{
struct dir_data *dirp;
int fd;
GetDIR(dir, dirp);
fd = dirfd(dirp->dir);
if (fd == -1)
rb_sys_fail("dirfd");
return INT2NUM(fd);
} Возвращает дескриптор файла, используемый в dir.
d = Dir.new("..")
d.fileno #=> 8
Этот метод использует функцию dirfd(), определённую POSIX 2008. NotImplementedError генерируется на других платформах, таких как Windows, которые не предоставляют эту функцию.
static VALUE
dir_inspect(VALUE dir)
{
struct dir_data *dirp;
TypedData_Get_Struct(dir, struct dir_data, &dir_data_type, dirp);
if (!NIL_P(dirp->path)) {
VALUE str = rb_str_new_cstr("#<");
rb_str_append(str, rb_class_name(CLASS_OF(dir)));
rb_str_cat2(str, ":");
rb_str_append(str, dirp->path);
rb_str_cat2(str, ">");
return str;
}
return rb_funcallv(dir, idTo_s, 0, 0);
} Возвращает строку, описывающую этот объект Dir.
static VALUE
dir_path(VALUE dir)
{
struct dir_data *dirp;
TypedData_Get_Struct(dir, struct dir_data, &dir_data_type, dirp);
if (NIL_P(dirp->path)) return Qnil;
return rb_str_dup(dirp->path);
} Возвращает путь, переданный конструктору dir.
d = Dir.new("..")
d.path #=> ".."
static VALUE
dir_tell(VALUE dir)
{
struct dir_data *dirp;
long pos;
GetDIR(dir, dirp);
pos = telldir(dirp->dir);
return rb_int2inum(pos);
} Возвращает текущую позицию в dir. См. также Dir#seek.
d = Dir.new("testdir")
d.tell #=> 0
d.read #=> "."
d.tell #=> 12
static VALUE
dir_set_pos(VALUE dir, VALUE pos)
{
dir_seek(dir, pos);
return pos;
} Синоним для Dir#seek, но возвращает параметр позиции.
d = Dir.new("testdir") #=> #<Dir:0x401b3c40>
d.read #=> "."
i = d.pos #=> 12
d.read #=> ".."
d.pos = i #=> 12
d.read #=> ".."
static VALUE
dir_read(VALUE dir)
{
struct dir_data *dirp;
struct dirent *dp;
GetDIR(dir, dirp);
errno = 0;
if ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc);
}
else {
int e = errno;
if (e != 0) rb_syserr_fail(e, 0);
return Qnil; /* end of stream */
}
} Читает следующую запись из dir и возвращает её как строку. Возвращает nil в конце потока.
d = Dir.new("testdir")
d.read #=> "."
d.read #=> ".."
d.read #=> "config.h"
static VALUE
dir_rewind(VALUE dir)
{
struct dir_data *dirp;
GetDIR(dir, dirp);
rewinddir(dirp->dir);
return dir;
} Перемещает dir к первой записи.
d = Dir.new("testdir")
d.read #=> "."
d.rewind #=> #<Dir:0x401b3fb0>
d.read #=> "."
static VALUE
dir_seek(VALUE dir, VALUE pos)
{
struct dir_data *dirp;
long p = NUM2LONG(pos);
GetDIR(dir, dirp);
seekdir(dirp->dir, p);
return dir;
} Перемещает указатель в определённое место в dir. целое должно быть значением, возвращённым Dir#tell.
d = Dir.new("testdir") #=> #<Dir:0x401b3c40>
d.read #=> "."
i = d.tell #=> 12
d.read #=> ".."
d.seek(i) #=> #<Dir:0x401b3c40>
d.read #=> ".."
static VALUE
dir_tell(VALUE dir)
{
struct dir_data *dirp;
long pos;
GetDIR(dir, dirp);
pos = telldir(dirp->dir);
return rb_int2inum(pos);
} Возвращает текущую позицию в dir. См. также Dir#seek.
d = Dir.new("testdir")
d.tell #=> 0
d.read #=> "."
d.tell #=> 12
static VALUE
dir_path(VALUE dir)
{
struct dir_data *dirp;
TypedData_Get_Struct(dir, struct dir_data, &dir_data_type, dirp);
if (NIL_P(dirp->path)) return Qnil;
return rb_str_dup(dirp->path);
} Возвращает путь, переданный конструктору dir.
d = Dir.new("..")
d.path #=> ".."
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.