Dir
class Dir
父类:ObjectIncluded 模块:Enumerable
类的对象Dir
是表示底层文件系统中的目录的目录流。他们提供了多种方式来列出目录及其内容。另见File
。
这些示例中使用的目录包含两个常规文件(config.h
和main.rb
),父目录(..
)和目录本身(.
)。
Public Class Methods
Dir [字符串,字符串...]→数组显示源文件
相当于调用Dir.glob([string,...],0)
。
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
}
chdir(字符串)→0显示源文件
chdir( string ) {| path | block } → anObject
将进程的当前工作目录更改为给定的字符串。当没有参数的情况下调用时,将目录更改为环境变量的值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
produces:
/var/spool/mail
/tmp
/usr
/tmp
/var/spool/mail
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
}
chroot( string ) → 0 Show source
改变这个过程的文件系统根目录。只有特权进程才能进行此调用。不适用于所有平台。在Unix系统上,请参阅chroot(2)
更多信息。
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
}
delete( string ) → 0 Show source
删除指定的目录。引发SystemCallError
目录不为空的子类。
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
}
空?(路径名)→真或假显示源
返回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};
GlobPathValue(dirname, FALSE
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;
}
entries( dirname ) → array Show source
entries( dirname, encoding: enc ) → array
返回包含给定目录中所有文件名的数组。SystemCallError
如果指定的目录不存在,将引发一次。
可选的enc
参数指定目录的编码。如果未指定,则使用文件系统编码。
Dir.entries("testdir") #=> [".", "..", "config.h", "main.rb"]
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
}
存在?(file_name)→true或false显示源
返回true
指定文件是否为目录,否则返回false
。
VALUE
rb_file_directory_p(void)
{
}
存在?(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 Show source
foreach( dirname, encoding: enc ) {| filename | block } → nil
foreach( dirname ) → an_enumerator
foreach( dirname, encoding: enc ) → an_enumerator
为指定目录中的每个条目调用一次块,将每个条目的文件名作为参数传递给块。
如果没有给出块,则返回一个枚举器。
Dir.foreach("testdir") {|x| puts "Got #{x}" }
produces:
Got .
Got ..
Got config.h
Got main.rb
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;
}
getwd → string Show source
以字符串形式返回此进程当前工作目录的路径。
Dir.chdir("/tmp") #=> 0
Dir.getwd #=> "/tmp"
Dir.pwd #=> "/tmp"
static VALUE
dir_s_getwd(VALUE dir)
{
return rb_dir_getwd(
}
glob( pattern, flags ) → matches Show source
glob( pattern, flags ) { |filename| block } → nil
展开pattern
,它是一个模式或模式字符串数组,并将结果作为matches
或提供给块的参数返回。
请注意,这种模式不是正则表达式,它更接近shell glob。有关flags
参数的含义,请参阅File.fnmatch 。请注意,区分大小写取决于您的系统(因此File :: FNM_CASEFOLD将被忽略),结果返回的顺序也一样。
*
匹配任何文件。可以被glob中的其他值限制。等同/ .* /x
于正则表达式。
*
匹配所有文件
c*
匹配以c
开头的所有文件
*c
匹配以c
结尾的所有文件
*c*
匹配其中的所有文件c
(包括开头或结尾)。
请注意,这不符合类Unix的隐藏文件(点文件)。为了将这些包含在匹配结果中,您必须使用File :: FNM_DOTMATCH标志或类似的东西"{*,.*}"
。
**
递归匹配目录。
?
匹配任何一个字符。等同/.{1}/
于正则表达式。
[set]
匹配任何一个字符set
。行为与Regexp中的字符集完全相同,包括集合negation([^a-z]
)。
{p,q}
匹配文字p
或文字q
。等同于正则表达式中的模式交替。
匹配文字的长度可能不止一个字符。可以指定两个以上的文字。
`\`
转义下一个元字符。
请注意,这意味着您不能在窗口上使用反斜杠作为glob的一部分,即Dir["c:\foo*"]
不能使用,Dir["c:/foo*"]
而是使用反斜杠。
Examples:
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"]
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;
}
home() → "/home/me" Show source
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 Show source
创建一个由字符串
命名的新目录,其权限由可选参数anInteger
指定。这些权限可能会被File::umask
NT 的值修改,并在NT上被忽略。SystemCallError
如果无法创建目录,则引发一个。另请参阅关于类文档中关于权限的讨论File
。
Dir.mkdir(File.join(Dir.home, ".foo"), 0700) #=> 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
}
mktmpdir(prefix_suffix=nil, *rest) { |path| ... } Show source
:: mktmpdir创建一个临时目录。
该目录使用0700权限创建。应用程序不应更改允许其他用户访问临时目录的权限。
目录名称的前缀和后缀由可选的第一个参数prefix_suffix指定
。
- 如果未指定或无,则使用“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..." }
如果给出了一个块,那么它将与目录的路径一致。在:: mktmpdir返回之前,使用FileUtils#remove_entry删除目录及其内容。该块的值将返回。
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
# 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
new( string ) → aDir Show source
new( string, encoding: enc ) → aDir
返回指定目录的新目录对象。
可选的enc
参数指定目录的编码。如果未指定,则使用文件系统编码。
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
}
}
GlobPathValue(dirname, FALSE
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;
}
open( string ) → aDir Show source
open( string, encoding: enc ) → aDir
open( string ) {| aDir | block } → anObject
open( string, encoding: enc ) {| aDir | block } → anObject
可选的enc
参数指定目录的编码。如果未指定,则使用文件系统编码。
没有阻止,open
是一个同义词Dir::new
。如果存在块,则将其作为参数传递给aDir
。该目录在块的结尾处关闭,Dir::open
返回该块的值。
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;
}
pwd → string Show source
以字符串形式返回此进程当前工作目录的路径。
Dir.chdir("/tmp") #=> 0
Dir.getwd #=> "/tmp"
Dir.pwd #=> "/tmp"
static VALUE
dir_s_getwd(VALUE dir)
{
return rb_dir_getwd(
}
rmdir( string ) → 0 Show source
删除指定的目录。引发SystemCallError
目录不为空的子类。
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
}
tmpdir() Show source
返回操作系统的临时文件路径。
# 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 Show source
删除指定的目录。引发SystemCallError
目录不为空的子类。
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
}
Public Instance Methods
close → nil Show source
关闭目录流。从Ruby 2.3开始,在关闭的Dir对象上调用此方法将被忽略。
d = Dir.new("testdir")
d.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;
}
each { |filename| block } → dir Show source
each → an_enumerator
为该目录中的每个条目调用一次该块,将每个条目的文件名作为参数传递给该块。
如果没有给出块,则返回一个枚举器。
d = Dir.new("testdir")
d.each {|x| puts "Got #{x}" }
produces:
Got .
Got ..
Got config.h
Got main.rb
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;
}
fileno → integer Show source
返回dir中
使用的文件描述符。
d = Dir.new("..")
d.fileno #=> 8
此方法使用由POSIX 2008定义的dirfd()函数。在其他平台(如Windows)上引发NotImplementedError,该平台不提供该函数。
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
}
inspect → string Show source
返回描述这个Dir对象的字符串。
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
构造函数的路径参数。
d = Dir.new("..")
d.path #=> ".."
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
}
pos→整数显示来源
返回目录
中的当前位置。另见Dir#seek
。
d = Dir.new("testdir")
d.tell #=> 0
d.read #=> "."
d.tell #=> 12
static VALUE
dir_tell(VALUE dir)
{
struct dir_data *dirp;
long pos;
GetDIR(dir, dirp
pos = telldir(dirp->dir
return rb_int2inum(pos
}
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_set_pos(VALUE dir, VALUE pos)
{
dir_seek(dir, pos
return pos;
}
read→字符串或零显示源
从dir
读取下一个条目并将其作为字符串返回。nil
在流尾部返回。
d = Dir.new("testdir")
d.read #=> "."
d.read #=> ".."
d.read #=> "config.h"
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 */
}
}
rewind → dir Show source
将dir
重新定位到第一个条目。
d = Dir.new("testdir")
d.read #=> "."
d.rewind #=> #<Dir:0x401b3fb0>
d.read #=> "."
static VALUE
dir_rewind(VALUE dir)
{
struct dir_data *dirp;
GetDIR(dir, dirp
rewinddir(dirp->dir
return dir;
}
seek(整数)→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_seek(VALUE dir, VALUE pos)
{
struct dir_data *dirp;
long p = NUM2LONG(pos
GetDIR(dir, dirp
seekdir(dirp->dir, p
return dir;
}
tell→整数显示源
返回目录
中的当前位置。另见Dir#seek
。
d = Dir.new("testdir")
d.tell #=> 0
d.read #=> "."
d.tell #=> 12
static VALUE
dir_tell(VALUE dir)
{
struct dir_data *dirp;
long pos;
GetDIR(dir, dirp
pos = telldir(dirp->dir
return rb_int2inum(pos
}
to_path → string or nil Show source
返回传递给dir
构造函数的路径参数。
d = Dir.new("..")
d.path #=> ".."
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
}