Spec-Zone.ru › Ruby 2.4

класс Dir

Родитель:
Объект
Включенные модули:
Enumerable

Объекты класса Dir представляют собой потоки каталогов, представляющие каталоги в файловой системе. Они предоставляют различные способы перечисления каталогов и их содержимого. Смотрите также File.

Каталог, используемый в этих примерах, содержит две обычные файлы (config.h и main.rb), родительский каталог (..) и сам каталог (.).

Публичные методы класса

Dir[ string [, string ...] ] → массив Показать исходный код
static VALUE
dir_s_aref(int argc, VALUE *argv, VALUE obj)
{
    if (argc == 1) {
        return rb_push_glob(argv[0], 0);
    }
    return dir_globs(argc, argv, 0);
}

Эквивалентно вызову Dir.glob([string,...],0).

chdir( [ string] ) → 0 Показать исходный код
chdir( [ string] ) {| path | block } → anObject
static VALUE
dir_s_chdir(int argc, VALUE *argv, VALUE obj)
{
    VALUE path = Qnil;

    if (rb_scan_args(argc, argv, "01", &path) == 1) {
        FilePathValue(path);
        path = rb_str_encode_ospath(path);
    }
    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);
    }
    dir_chdir(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
chroot( string ) → 0 Показать исходный код
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) для получения дополнительной информации.

delete( string ) → 0 Показать исходный код
static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
    dir = check_dirname(dir);
    if (rmdir(RSTRING_PTR(dir)) < 0)
        rb_sys_fail_path(dir);

    return INT2FIX(0);
}

Удаляет указанный каталог. Вызывает исключение подкласса SystemCallError если каталог не пуст.

empty?(path_name) → true или false Показать исходный код
static VALUE
rb_dir_s_empty_p(VALUE obj, VALUE dirname)
{
    DIR *dir;
    struct dirent *dp;
    VALUE result = Qtrue, 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

    dir = opendir(path);
    if (!dir) {
        int e = errno;
        switch (rb_gc_for_fd(e)) {
          default:
            dir = opendir(path);
            if (dir) break;
            e = errno;
            /* fall through */
          case 0:
            if (false_on_notdir && e == ENOTDIR) return Qfalse;
            rb_syserr_fail_path(e, orig);
        }
    }
    errno = 0;
    while ((dp = READDIR(dir, NULL)) != NULL) {
        if (!to_be_skipped(dp)) {
            result = Qfalse;
            break;
        }
    }
    closedir(dir);
    return result;
}

Возвращает true если указанный файл является пустым каталогом, false если это не каталог или каталог не пустой.

entries( dirname ) → массив Показать исходный код
entries( dirname, encoding: enc ) → массив
static VALUE
dir_entries(int argc, VALUE *argv, VALUE io)
{
    VALUE dir;

    dir = dir_open_dir(argc, argv);
    return rb_ensure(rb_Array, dir, dir_close, dir);
}

Возвращает массив, содержащий все имена файлов в указанном каталоге. Вызовет SystemCallError если указанного каталога не существует.

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

Dir.entries("testdir")   #=> [".", "..", "config.h", "main.rb"]
exist?(file_name) → true или false Показать исходный код
VALUE
rb_file_directory_p(void)
{
}

Возвращает true если указанный файл является каталогом, false в противном случае.

exists?(file_name) → 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);
}

Метод устарел. Не использовать.

foreach( dirname ) {| filename | block } → nil Показать исходный код
foreach( dirname, encoding: enc ) {| filename | block } → nil
foreach( dirname ) → итератор
foreach( dirname, encoding: enc ) → итератор
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
getwd → строка Показать исходный код
static VALUE
dir_s_getwd(VALUE dir)
{
    return rb_dir_getwd();
}

Возвращает путь к текущему рабочему каталогу этого процесса в виде строки.

Dir.chdir("/tmp")   #=> 0
Dir.getwd           #=> "/tmp"
Dir.pwd             #=> "/tmp"
glob( pattern, [flags] ) → совпадения Показать исходный код
glob( pattern, [flags] ) { |filename| block } → nil
static VALUE
dir_s_glob(int argc, VALUE *argv, VALUE obj)
{
    VALUE str, rflags, ary;
    int flags;

    if (rb_scan_args(argc, argv, "11", &str, &rflags) == 2)
        flags = NUM2INT(rflags);
    else
        flags = 0;

    ary = rb_check_array_type(str);
    if (NIL_P(ary)) {
        ary = rb_push_glob(str, flags);
    }
    else {
        VALUE v = ary;
        ary = dir_globs(RARRAY_LEN(v), RARRAY_CONST_PTR(v), flags);
        RB_GC_GUARD(v);
    }

    if (rb_block_given_p()) {
        rb_ary_each(ary);
        return Qnil;
    }
    return ary;
}

Расширяет pattern, что является массивом шаблонов или строкой-шаблоном, и возвращает результаты как matches или как аргументы, переданные в блок.

Обратите внимание, что этот шаблон не является регулярным выражением, он ближе к оболочке glob. См. File.fnmatch для значения параметра flags. Обратите внимание, что чувствительность к регистру зависит от вашей системы (поэтому File::FNM_CASEFOLD игнорируется), как и порядок возврата результатов.

*

Совпадает с любым файлом. Может быть ограничен другими значениями в glob. Эквивалентно / .* /x в регулярных выражениях.

*

Совпадает со всеми файлами

c*

Совпадает со всеми файлами, начинающимися с c

*c

Совпадает со всеми файлами, заканчивающимися на c

*c*

Совпадает со всеми файлами, содержащими c (в том числе в начале или конце).

Обратите внимание, что это не будет соответствовать скрытым файлам Unix-подобных систем (файлам с точкой). Для включения таких результатов в совпадения необходимо использовать флаг 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"]

rbfiles = File.join("**", "*.rb")
Dir.glob(rbfiles)                   #=> ["main.rb",
                                    #    "lib/song.rb",
                                    #    "lib/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"]
home() → "/home/me" Показать исходный код
home("root") → "/root"
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));

}

Возвращает домашний каталог текущего пользователя или указанного пользователя, если он задан.

mkdir( string [, integer] ) → 0 Показать исходный код
static VALUE
dir_s_mkdir(int argc, VALUE *argv, VALUE obj)
{
    VALUE path, vmode;
    int mode;

    if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) {
        mode = NUM2INT(vmode);
    }
    else {
        mode = 0777;
    }

    path = check_dirname(path);
    if (mkdir(RSTRING_PTR(path), mode) == -1)
        rb_sys_fail_path(path);

    return INT2FIX(0);
}

Создает новый каталог с именем string и разрешениями, указанными необязательным параметром anInteger. Разрешения могут быть изменены значением File::umask, и игнорируются в NT. Вызывает исключение SystemCallError если каталог не может быть создан. См. также обсуждение разрешений в документации класса для File.

Dir.mkdir(File.join(Dir.home, ".foo"), 0700) #=> 0
mktmpdir(prefix_suffix=nil, *rest) { |path| ... } Показать исходный код
# File lib/tmpdir.rb, line 84
def self.mktmpdir(prefix_suffix=nil, *rest)
  path = Tmpname.create(prefix_suffix || "d", *rest) {|n| mkdir(n, 0700)}
  if block_given?
    begin
      yield path
    ensure
      stat = File.stat(File.dirname(path))
      if stat.world_writable? and !stat.sticky?
        raise ArgumentError, "parent directory is world writable but not sticky"
      end
      FileUtils.remove_entry path
    end
  else
    path
  end
end

::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" }

Директория создаётся в ::tmpdir или в необязательном втором аргументе tmpdir, если указано ненулевое значение.

Dir.mktmpdir {|dir| dir is "#{Dir.tmpdir}/d..." }
Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }

Если задан блок, он вызывается с путём к директории. Директория и её содержимое удаляются с помощью FileUtils#remove_entry перед тем, как ::mktmpdir вернёт значение. Возвращается результат выполнения блока.

Dir.mktmpdir {|dir|
  # use the directory...
  open("#{dir}/foo", "w") { ... }
}

Если блок не задан, возвращается путь к директории. В этом случае ::mktmpdir не удаляет директорию.

dir = Dir.mktmpdir
begin
  # use the directory...
  open("#{dir}/foo", "w") { ... }
ensure
  # remove the directory.
  FileUtils.remove_entry dir
end
new( string ) → aDir Показать исходный код
new( string, encoding: enc ) → aDir
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;
    dp->path = Qnil;
    dp->enc = fsenc;
    path = RSTRING_PTR(dirname);
    dp->dir = opendir(path);
    if (dp->dir == NULL) {
        int e = errno;
        if (rb_gc_for_fd(e)) {
            dp->dir = opendir(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(path);
            }
        }
#endif
        if (dp->dir == NULL) {
            RB_GC_GUARD(dirname);
            rb_syserr_fail_path(e, orig);
        }
    }
    dp->path = orig;

    return dir;
}

Возвращает новый объект директории для указанной директории.

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

open( string ) → aDir Показать исходный код
open( string, encoding: enc ) → aDir
open( string ) {| aDir | block } → anObject
open( string, encoding: enc ) {| aDir | block } → anObject
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;
}

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

Без блока, open — это синоним для Dir::new. Если блок присутствует, ему передаётся aDir в качестве параметра. Директория закрывается в конце блока, и Dir::open возвращает значение блока.

pwd → string Показать исходный код
static VALUE
dir_s_getwd(VALUE dir)
{
    return rb_dir_getwd();
}

Возвращает путь к текущей рабочей директории этого процесса в виде строки.

Dir.chdir("/tmp")   #=> 0
Dir.getwd           #=> "/tmp"
Dir.pwd             #=> "/tmp"
rmdir( string ) → 0 Показать исходный код
static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
    dir = check_dirname(dir);
    if (rmdir(RSTRING_PTR(dir)) < 0)
        rb_sys_fail_path(dir);

    return INT2FIX(0);
}

Удаляет указанную директорию. Вызывает подкласс SystemCallError , если директория не пуста.

tmpdir() Показать исходный код
# File lib/tmpdir.rb, line 20
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

Возвращает путь к временной директории операционной системы.

unlink( string ) → 0 Показать исходный код
static VALUE
dir_s_rmdir(VALUE obj, VALUE dir)
{
    dir = check_dirname(dir);
    if (rmdir(RSTRING_PTR(dir)) < 0)
        rb_sys_fail_path(dir);

    return INT2FIX(0);
}

Удаляет указанную директорию. Вызывает подкласс SystemCallError , если директория не пуста.

Общедоступные методы экземпляров

close → nil Показать исходный код
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
each { |filename| block } → dir Показать исходный код
each → an_enumerator
static VALUE
dir_each(VALUE dir)
{
    struct dir_data *dirp;
    struct dirent *dp;
    IF_NORMALIZE_UTF8PATH(int norm_p);

    RETURN_ENUMERATOR(dir, 0, 0);
    GetDIR(dir, dirp);
    rewinddir(dirp->dir);
    IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp->dir, RSTRING_PTR(dirp->path)));
    while ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) {
        const char *name = dp->d_name;
        size_t namlen = NAMLEN(dp);
        VALUE path;
#if NORMALIZE_UTF8PATH
        if (norm_p && has_nonascii(name, namlen) &&
            !NIL_P(path = rb_str_normalize_ospath(name, namlen))) {
            path = rb_external_str_with_enc(path, dirp->enc);
        }
        else
#endif
        path = rb_external_str_new_with_enc(name, namlen, dirp->enc);
        rb_yield(path);
        if (dirp->dir == NULL) dir_closed();
    }
    return dir;
}

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

Если блок не задан, возвращается перечислитель.

d = Dir.new("testdir")
d.each  {|x| puts "Got #{x}" }

выводит:

Got .
Got ..
Got config.h
Got main.rb
fileno → integer Показать исходный код
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, которые не предоставляют эту функцию.

inspect → string Показать исходный код
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, rb_intern("to_s"), 0, 0);
}

Возвращает строку, описывающую этот объект Dir.

path → string or nil Показать исходный код
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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API