File::Stat
class File::Stat
Parent:ObjectIncluded modules:Comparable
类的对象File::Stat
封装了对象的公共状态信息File
。信息在File::Stat
创建对象时记录; 在该点后对文件所做的更改不会被反映出来。File::Stat
对象是由归国IO#stat
,File::stat
,File#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#dev
或nil
的主要部分。
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#dev
或nil
的小部分。
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#rdev
或nil
的主要部分。
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#rdev
或nil
的小部分。
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;
}