Ruby 2.4

File::Stat

class File::Stat

Parent:ObjectIncluded modules:Comparable

类的对象File::Stat封装了对象的公共状态信息File。信息在File::Stat创建对象时记录; 在该点后对文件所做的更改不会被反映出来。File::Stat对象是由归国IO#statFile::statFile#lstat,和File::lstat。这些方法中的很多都会返回特定于平台的值,并不是所有的值在所有系统上都有意义。另见Kernel#test

Public Class Methods

File::Stat.new(file_name) → stat Show source

为给定文件名创建一个File :: Stat对象(如果该文件不存在,则引发异常)。

static VALUE rb_stat_init(VALUE obj, VALUE fname) { struct stat st, *nst; FilePathValue(fname fname = rb_str_encode_ospath(fname if (STAT(StringValueCStr(fname), &st) == -1) { rb_sys_fail_path(fname } if (DATA_PTR(obj)) { xfree(DATA_PTR(obj) DATA_PTR(obj) = NULL; } nst = ALLOC(struct stat *nst = st; DATA_PTR(obj) = nst; return Qnil; }

Public Instance Methods

stat <=> other_stat → -1, 0, 1, nil Show source

通过比较它们各自的修改时间来比较File0::Stat对象。

nil如果other_stat不是File::Stat对象则返回

f1 = File.new("f1", "w") sleep 1 f2 = File.new("f2", "w") f1.stat <=> f2.stat #=> -1

static VALUE rb_stat_cmp(VALUE self, VALUE other) { if (rb_obj_is_kind_of(other, rb_obj_class(self))) { struct timespec ts1 = stat_mtimespec(get_stat(self) struct timespec ts2 = stat_mtimespec(get_stat(other) if (ts1.tv_sec == ts2.tv_sec) { if (ts1.tv_nsec == ts2.tv_nsec) return INT2FIX(0 if (ts1.tv_nsec < ts2.tv_nsec) return INT2FIX(-1 return INT2FIX(1 } if (ts1.tv_sec < ts2.tv_sec) return INT2FIX(-1 return INT2FIX(1 } return Qnil; }

atime → time Show source

将此文件的上次访问时间返回为类的对象Time

File.stat("testfile").atime #=> Wed Dec 31 18:00:00 CST 1969

static VALUE rb_stat_atime(VALUE self) { return stat_atime(get_stat(self) }

birthtime → aTime Show source

返回统计的出生时间。

如果平台没有生日,则引发NotImplementedError。

File.write("testfile", "foo") sleep 10 File.write("testfile", "bar") sleep 10 File.chmod(0644, "testfile") sleep 10 File.read("testfile") File.stat("testfile").birthtime #=> 2014-02-24 11:19:17 +0900 File.stat("testfile").mtime #=> 2014-02-24 11:19:27 +0900 File.stat("testfile").ctime #=> 2014-02-24 11:19:37 +0900 File.stat("testfile").atime #=> 2014-02-24 11:19:47 +0900

static VALUE rb_stat_birthtime(VALUE self) { return stat_birthtime(get_stat(self) }

blksize → integer or nil Show source

返回本机文件系统的块大小。将在不支持此信息的平台上返回nil

File.stat("testfile").blksize #=> 4096

static VALUE rb_stat_blksize(VALUE self) { #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE return ULONG2NUM(get_stat(self)->st_blksize #else return Qnil; #endif }

blockdev? → true or false Show source

true如果文件是块设备,如果不是,或者操作false系统不支持此功能,则返回该文件。

File.stat("testfile").blockdev? #=> false File.stat("/dev/hda1").blockdev? #=> true

static VALUE rb_stat_b(VALUE obj) { #ifdef S_ISBLK if (S_ISBLK(get_stat(obj)->st_mode)) return Qtrue; #endif return Qfalse; }

blocks → integer or nil Show source

返回为此文件分配的本机文件系统块的数量,或者nil操作系统不支持此功能。

File.stat("testfile").blocks #=> 2

static VALUE rb_stat_blocks(VALUE self) { #ifdef HAVE_STRUCT_STAT_ST_BLOCKS # if SIZEOF_STRUCT_STAT_ST_BLOCKS > SIZEOF_LONG return ULL2NUM(get_stat(self)->st_blocks # else return ULONG2NUM(get_stat(self)->st_blocks # endif #else return Qnil; #endif }

chardev? → true or false Show source

返回true如果该文件是一个字符设备,false如果不是,或者如果操作系统不支持此功能。

File.stat("/dev/tty").chardev? #=> true

static VALUE rb_stat_c(VALUE obj) { if (S_ISCHR(get_stat(obj)->st_mode)) return Qtrue; return Qfalse; }

ctime → aTime Show source

返回stat的更改时间(也就是说,文件的时间目录信息已更改,而不是文件本身)。

请注意,在Windows(NTFS)上返回创建时间(出生时间)。

File.stat("testfile").ctime #=> Wed Apr 09 08:53:14 CDT 2003

static VALUE rb_stat_ctime(VALUE self) { return stat_ctime(get_stat(self) }

dev → integer Show source

返回表示stat所在设备的整数。

File.stat("testfile").dev #=> 774

static VALUE rb_stat_dev(VALUE self) { return DEVT2NUM(get_stat(self)->st_dev }

dev_major → integer Show source

返回File_Stat#devnil的主要部分。

File.stat("/dev/fd1").dev_major #=> 2 File.stat("/dev/tty").dev_major #=> 5

static VALUE rb_stat_dev_major(VALUE self) { #if defined(major) return DEVT2NUM(major(get_stat(self)->st_dev) #else return Qnil; #endif }

dev_minor → integer Show source

返回File_Stat#devnil的小部分。

File.stat("/dev/fd1").dev_minor #=> 1 File.stat("/dev/tty").dev_minor #=> 0

static VALUE rb_stat_dev_minor(VALUE self) { #if defined(minor) return DEVT2NUM(minor(get_stat(self)->st_dev) #else return Qnil; #endif }

directory?(file_name) → true or false Show source

如果指定的文件是目录或指向目录的符号链接,则返回true;否则返回false

file_name可以是IO对象。

File.directory?(".")

static VALUE rb_stat_d(VALUE obj) { if (S_ISDIR(get_stat(obj)->st_mode)) return Qtrue; return Qfalse; }

executable? → true or false Show source

true如果stat是可执行文件,或者操作系统不会将可执行文件与不可执行文件区分开来,则返回此。测试是使用流程的有效所有者进行的。

File.stat("testfile").executable? #=> false

static VALUE rb_stat_x(VALUE obj) { struct stat *st = get_stat(obj #ifdef USE_GETEUID if (geteuid() == 0) { return st->st_mode & S_IXUGO ? Qtrue : Qfalse; } #endif #ifdef S_IXUSR if (rb_stat_owned(obj)) return st->st_mode & S_IXUSR ? Qtrue : Qfalse; #endif #ifdef S_IXGRP if (rb_stat_grpowned(obj)) return st->st_mode & S_IXGRP ? Qtrue : Qfalse; #endif #ifdef S_IXOTH if (!(st->st_mode & S_IXOTH)) return Qfalse; #endif return Qtrue; }

executable_real? → true or false Show source

executable?相同,但使用流程的真正所有者进行测试。

static VALUE rb_stat_X(VALUE obj) { struct stat *st = get_stat(obj #ifdef USE_GETEUID if (getuid() == 0) { return st->st_mode & S_IXUGO ? Qtrue : Qfalse; } #endif #ifdef S_IXUSR if (rb_stat_rowned(obj)) return st->st_mode & S_IXUSR ? Qtrue : Qfalse; #endif #ifdef S_IXGRP if (rb_group_member(get_stat(obj)->st_gid)) return st->st_mode & S_IXGRP ? Qtrue : Qfalse; #endif #ifdef S_IXOTH if (!(st->st_mode & S_IXOTH)) return Qfalse; #endif return Qtrue; }

file? → true or false Show source

返回true如果统计是一个普通文件(不是一个设备文件,管道,插座等)。

File.stat("testfile").file? #=> true

static VALUE rb_stat_f(VALUE obj) { if (S_ISREG(get_stat(obj)->st_mode)) return Qtrue; return Qfalse; }

ftype → string Show source

标识统计的类型。返回字符串是以下之一:“ file'',''directory'',''characterSpecial',''blockSpecial'',''fifo'',''link'',''socket''或''unknown''。

File.stat("/dev/tty").ftype #=> "characterSpecial"

static VALUE rb_stat_ftype(VALUE obj) { return rb_file_ftype(get_stat(obj) }

gid → integer Show source

返回stat的所有者的数字组ID 。

File.stat("testfile").gid #=> 500

static VALUE rb_stat_gid(VALUE self) { return GIDT2NUM(get_stat(self)->st_gid }

grpowned? → true or false Show source

如果进程的有效组标识与stat的组标识相同,则返回true 。在Windows NT上,返回false

File.stat("testfile").grpowned? #=> true File.stat("/etc/passwd").grpowned? #=> false

static VALUE rb_stat_grpowned(VALUE obj) { #ifndef _WIN32 if (rb_group_member(get_stat(obj)->st_gid)) return Qtrue; #endif return Qfalse; }

ino → integer Show source

返回stat的inode编号。

File.stat("testfile").ino #=> 1083669

static VALUE rb_stat_ino(VALUE self) { #ifdef _WIN32 struct stat *st = get_stat(self unsigned short *p2 = (unsigned short *)st; unsigned int *p4 = (unsigned int *)st; uint64_t r; r = p2[2]; r <<= 16; r |= p2[7]; r <<= 32; r |= p4[5]; return ULL2NUM(r #elif SIZEOF_STRUCT_STAT_ST_INO > SIZEOF_LONG return ULL2NUM(get_stat(self)->st_ino #else return ULONG2NUM(get_stat(self)->st_ino #endif }

inspect → string Show source

生成一个很好格式化的统计描述。

File.stat("/etc/passwd").inspect #=> "#<File::Stat dev=0xe000005, ino=1078078, mode=0100644, # nlink=1, uid=0, gid=0, rdev=0x0, size=1374, blksize=4096, # blocks=8, atime=Wed Dec 10 10:16:12 CST 2003, # mtime=Fri Sep 12 15:41:41 CDT 2003, # ctime=Mon Oct 27 11:20:27 CST 2003, # birthtime=Mon Aug 04 08:13:49 CDT 2003>"

static VALUE rb_stat_inspect(VALUE self) { VALUE str; size_t i; static const struct { const char *name; VALUE (*func)(VALUE } member[] = { {"dev", rb_stat_dev}, {"ino", rb_stat_ino}, {"mode", rb_stat_mode}, {"nlink", rb_stat_nlink}, {"uid", rb_stat_uid}, {"gid", rb_stat_gid}, {"rdev", rb_stat_rdev}, {"size", rb_stat_size}, {"blksize", rb_stat_blksize}, {"blocks", rb_stat_blocks}, {"atime", rb_stat_atime}, {"mtime", rb_stat_mtime}, {"ctime", rb_stat_ctime}, #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) {"birthtime", rb_stat_birthtime}, #endif }; struct stat* st; TypedData_Get_Struct(self, struct stat, &stat_data_type, st if (!st) { return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self) } str = rb_str_buf_new2("#<" rb_str_buf_cat2(str, rb_obj_classname(self) rb_str_buf_cat2(str, " " for (i = 0; i < sizeof(member)/sizeof(member[0] i++) { VALUE v; if (i > 0) { rb_str_buf_cat2(str, ", " } rb_str_buf_cat2(str, member[i].name rb_str_buf_cat2(str, "=" v = (*member[i].func)(self if (i == 2) { /* mode */ rb_str_catf(str, "0%lo", (unsigned long)NUM2ULONG(v) } else if (i == 0 || i == 6) { /* dev/rdev */ rb_str_catf(str, "0x%"PRI_DEVT_PREFIX"x", NUM2DEVT(v) } else { rb_str_append(str, rb_inspect(v) } } rb_str_buf_cat2(str, ">" OBJ_INFECT(str, self return str; }

mode → integer Show source

返回一个表示stat的权限位的整数。这些位的含义与平台有关;在Unix系统上,请参阅stat(2)

File.chmod(0644, "testfile") #=> 1 s = File.stat("testfile") sprintf("%o", s.mode) #=> "100644"

static VALUE rb_stat_mode(VALUE self) { return UINT2NUM(ST2UINT(get_stat(self)->st_mode) }

mtime → aTime Show source

返回stat的修改时间。

File.stat("testfile").mtime #=> Wed Apr 09 08:53:14 CDT 2003

static VALUE rb_stat_mtime(VALUE self) { return stat_mtime(get_stat(self) }

nlink → integer Show source

返回到统计的硬链接的数量。

File.stat("testfile").nlink #=> 1 File.link("testfile", "testfile.bak") #=> 0 File.stat("testfile").nlink #=> 2

static VALUE rb_stat_nlink(VALUE self) { return UINT2NUM(get_stat(self)->st_nlink }

owned? → true or false Show source

如果进程的有效用户标识与stat的所有者相同,则返回true

File.stat("testfile").owned? #=> true File.stat("/etc/passwd").owned? #=> false

static VALUE rb_stat_owned(VALUE obj) { if (get_stat(obj)->st_uid == geteuid()) return Qtrue; return Qfalse; }

pipe? → true or false Show source

如果操作系统支持管道并且stat是管道,则返回true;否则返回false

static VALUE rb_stat_p(VALUE obj) { #ifdef S_IFIFO if (S_ISFIFO(get_stat(obj)->st_mode)) return Qtrue; #endif return Qfalse; }

rdev → integer or nil Show source

返回表示stat所在的设备类型的整数。返回nil如果操作系统不支持此功能。

File.stat("/dev/fd1").rdev #=> 513 File.stat("/dev/tty").rdev #=> 1280

static VALUE rb_stat_rdev(VALUE self) { #ifdef HAVE_STRUCT_STAT_ST_RDEV return DEVT2NUM(get_stat(self)->st_rdev #else return Qnil; #endif }

rdev_major → integer Show source

返回File_Stat#rdevnil的主要部分。

File.stat("/dev/fd1").rdev_major #=> 2 File.stat("/dev/tty").rdev_major #=> 5

static VALUE rb_stat_rdev_major(VALUE self) { #if defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(major) return DEVT2NUM(major(get_stat(self)->st_rdev) #else return Qnil; #endif }

rdev_minor → integer Show source

返回File_Stat#rdevnil的小部分。

File.stat("/dev/fd1").rdev_minor #=> 1 File.stat("/dev/tty").rdev_minor #=> 0

static VALUE rb_stat_rdev_minor(VALUE self) { #if defined(HAVE_STRUCT_STAT_ST_RDEV) && defined(minor) return DEVT2NUM(minor(get_stat(self)->st_rdev) #else return Qnil; #endif }

readable? → true or false Show source

如果stat可以被此进程的有效用户标识读取,则返回true

File.stat("testfile").readable? #=> true

static VALUE rb_stat_r(VALUE obj) { struct stat *st = get_stat(obj #ifdef USE_GETEUID if (geteuid() == 0) return Qtrue; #endif #ifdef S_IRUSR if (rb_stat_owned(obj)) return st->st_mode & S_IRUSR ? Qtrue : Qfalse; #endif #ifdef S_IRGRP if (rb_stat_grpowned(obj)) return st->st_mode & S_IRGRP ? Qtrue : Qfalse; #endif #ifdef S_IROTH if (!(st->st_mode & S_IROTH)) return Qfalse; #endif return Qtrue; }

readable_real? → true or false Show source

如果stat可以被该进程的真实用户ID读取,则返回true

File.stat("testfile").readable_real? #=> true

static VALUE rb_stat_R(VALUE obj) { struct stat *st = get_stat(obj #ifdef USE_GETEUID if (getuid() == 0) return Qtrue; #endif #ifdef S_IRUSR if (rb_stat_rowned(obj)) return st->st_mode & S_IRUSR ? Qtrue : Qfalse; #endif #ifdef S_IRGRP if (rb_group_member(get_stat(obj)->st_gid)) return st->st_mode & S_IRGRP ? Qtrue : Qfalse; #endif #ifdef S_IROTH if (!(st->st_mode & S_IROTH)) return Qfalse; #endif return Qtrue; }

setgid? → true or false Show source

如果stat具有设置的set-group-id权限位,false则返回结果true,如果不存在或者操作系统不支持此功能。

File.stat("/usr/sbin/lpc").setgid? #=> true

static VALUE rb_stat_sgid(VALUE obj) { #ifdef S_ISGID if (get_stat(obj)->st_mode & S_ISGID) return Qtrue; #endif return Qfalse; }

setuid? → true or false Show source

返回true如果统计有设置用户ID权限位设置,false如果没有,或者如果操作系统不支持此功能。

File.stat("/bin/su").setuid? #=> true

static VALUE rb_stat_suid(VALUE obj) { #ifdef S_ISUID if (get_stat(obj)->st_mode & S_ISUID) return Qtrue; #endif return Qfalse; }

size → integer Show source

以字节为单位返回统计的大小。

File.stat("testfile").size #=> 66

static VALUE rb_stat_size(VALUE self) { return OFFT2NUM(get_stat(self)->st_size }

size → integer Show source

以字节为单位返回统计的大小。

File.stat("testfile").size #=> 66

static VALUE rb_stat_s(VALUE obj) { off_t size = get_stat(obj)->st_size; if (size == 0) return Qnil; return OFFT2NUM(size }

socket? → true or false Show source

返回true如果统计是一个socket,如果不是false操作系统不,或者如果支持此功能。

File.stat("testfile").socket? #=> false

static VALUE rb_stat_S(VALUE obj) { #ifdef S_ISSOCK if (S_ISSOCK(get_stat(obj)->st_mode)) return Qtrue; #endif return Qfalse; }

sticky? → true or false Show source

返回true如果统计有粘性位设置,false如果没有,或者如果操作系统不支持此功能。

File.stat("testfile").sticky? #=> false

static VALUE rb_stat_sticky(VALUE obj) { #ifdef S_ISVTX if (get_stat(obj)->st_mode & S_ISVTX) return Qtrue; #endif return Qfalse; }

symlink? → true or false Show source

返回true如果统计是一个符号链接,false如果不是,或者如果操作系统不支持此功能。由于File::stat自动跟随符号链接,symlink?将始终false针对由返回的对象File::stat

File.symlink("testfile", "alink") #=> 0 File.stat("alink").symlink? #=> false File.lstat("alink").symlink? #=> true

static VALUE rb_stat_l(VALUE obj) { #ifdef S_ISLNK if (S_ISLNK(get_stat(obj)->st_mode)) return Qtrue; #endif return Qfalse; }

uid → integer Show source

返回stat所有者的数字用户标识。

File.stat("testfile").uid #=> 501

static VALUE rb_stat_uid(VALUE self) { return UIDT2NUM(get_stat(self)->st_uid }

world_readable? → integer or nil Show source

如果stat可被他人读取,则返回一个表示stat的文件权限位的整数。nil否则返回。这些位的含义与平台有关; 在Unix系统上,请参阅stat(2)

m = File.stat("/etc/passwd").world_readable? #=> 420 sprintf("%o", m) #=> "644"

static VALUE rb_stat_wr(VALUE obj) { #ifdef S_IROTH struct stat *st = get_stat(obj if ((st->st_mode & (S_IROTH)) == S_IROTH) { return UINT2NUM(st->st_mode & (S_IRUGO|S_IWUGO|S_IXUGO) } else { return Qnil; } #endif }

world_writable? → integer or nil Show source

如果stat可由其他人写入,则返回一个表示stat的文件权限位的整数。nil否则返回。这些位的含义与平台有关; 在Unix系统上,请参阅stat(2)

m = File.stat("/tmp").world_writable? #=> 511 sprintf("%o", m) #=> "777"

static VALUE rb_stat_ww(VALUE obj) { #ifdef S_IROTH struct stat *st = get_stat(obj if ((st->st_mode & (S_IWOTH)) == S_IWOTH) { return UINT2NUM(st->st_mode & (S_IRUGO|S_IWUGO|S_IXUGO) } else { return Qnil; } #endif }

writable? → true or false Show source

如果stat可由此进程的有效用户标识写入,则返回true

File.stat("testfile").writable? #=> true

static VALUE rb_stat_w(VALUE obj) { struct stat *st = get_stat(obj #ifdef USE_GETEUID if (geteuid() == 0) return Qtrue; #endif #ifdef S_IWUSR if (rb_stat_owned(obj)) return st->st_mode & S_IWUSR ? Qtrue : Qfalse; #endif #ifdef S_IWGRP if (rb_stat_grpowned(obj)) return st->st_mode & S_IWGRP ? Qtrue : Qfalse; #endif #ifdef S_IWOTH if (!(st->st_mode & S_IWOTH)) return Qfalse; #endif return Qtrue; }

writable_real? → true or false Show source

如果stat可由此进程的实际用户标识写入,则返回true

File.stat("testfile").writable_real? #=> true

static VALUE rb_stat_W(VALUE obj) { struct stat *st = get_stat(obj #ifdef USE_GETEUID if (getuid() == 0) return Qtrue; #endif #ifdef S_IWUSR if (rb_stat_rowned(obj)) return st->st_mode & S_IWUSR ? Qtrue : Qfalse; #endif #ifdef S_IWGRP if (rb_group_member(get_stat(obj)->st_gid)) return st->st_mode & S_IWGRP ? Qtrue : Qfalse; #endif #ifdef S_IWOTH if (!(st->st_mode & S_IWOTH)) return Qfalse; #endif return Qtrue; }

zero? → true or false Show source

如果stat是一个零长度文件,则返回true;除此以外false

File.stat("testfile").zero? #=> false

static VALUE rb_stat_z(VALUE obj) { if (get_stat(obj)->st_size == 0) return Qtrue; return Qfalse; }