模块 FileTest
FileTest 实现了类似于 File::Stat 中使用的文件测试操作。它作为一个独立的模块存在,并且它的方法也都被隐式地添加到 File 类中。(请注意,这不是通过包含实现的:解释器作弊了)。
公共实例方法
源
static VALUE
rb_file_blockdev_p(VALUE obj, VALUE fname)
{
#ifndef S_ISBLK
# ifdef S_IFBLK
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
# else
# define S_ISBLK(m) (0) /* anytime false */
# endif
#endif
#ifdef S_ISBLK
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISBLK(st.st_mode)) return Qtrue;
#endif
return Qfalse;
}
如果 filepath 指向块设备,则返回 true,否则返回 false
File.blockdev?('/dev/sda1') # => true File.blockdev?(File.new('t.tmp')) # => false
源
static VALUE
rb_file_chardev_p(VALUE obj, VALUE fname)
{
#ifndef S_ISCHR
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISCHR(st.st_mode)) return Qtrue;
return Qfalse;
}
如果 filepath 指向字符设备,则返回 true,否则返回 false。
File.chardev?($stdin) # => true File.chardev?('t.txt') # => false
源
VALUE
rb_file_directory_p(VALUE obj, VALUE fname)
{
#ifndef S_ISDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISDIR(st.st_mode)) return Qtrue;
return Qfalse;
}
给定字符串 object,如果 path 是指向目录的字符串路径,或者是指向目录的符号链接,则返回 true;否则返回 false。
File.directory?('.') # => true File.directory?('foo') # => false File.symlink('.', 'dirlink') # => 0 File.directory?('dirlink') # => true File.symlink('t,txt', 'filelink') # => 0 File.directory?('filelink') # => false
参数 path 可以是 IO 对象。
源
static VALUE
rb_file_executable_p(VALUE obj, VALUE fname)
{
return RBOOL(rb_eaccess(fname, X_OK) >= 0);
}
如果指定的文件可以通过此进程的有效用户和组 ID 执行,则返回 true。 请参见 eaccess(3)。
Windows 不支持与读取权限分开的执行权限。 在 Windows 上,只有当文件以 .bat、.cmd、.com 或 .exe 结尾时,才会被认为是可执行文件。
请注意,某些操作系统级别的安全功能可能导致此方法返回 true,即使该文件对于有效用户/组来说是不可执行的。
源
static VALUE
rb_file_executable_real_p(VALUE obj, VALUE fname)
{
return RBOOL(rb_access(fname, X_OK) >= 0);
}
如果指定的文件可以通过此进程的真实用户和组 ID 执行,则返回 true。 请参见 access(3)。
Windows 不支持与读取权限分开的执行权限。 在 Windows 上,只有当文件以 .bat、.cmd、.com 或 .exe 结尾时,才会被认为是可执行文件。
请注意,某些操作系统级别的安全功能可能导致此方法返回 true,即使该文件对于真实用户/组来说是不可执行的。
源
static VALUE
rb_file_exist_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
return Qtrue;
}
如果指定的文件存在,则返回 true。
file_name 可以是 IO 对象。
“文件存在”意味着 stat() 或 fstat() 系统调用成功。
源
static VALUE
rb_file_file_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
return RBOOL(S_ISREG(st.st_mode));
}
如果指定的 file 存在并且是一个普通文件,则返回 true。
file 可以是 IO 对象。
如果 file 参数是符号链接,它将解析该符号链接并使用该链接引用的文件。
源
static VALUE
rb_file_grpowned_p(VALUE obj, VALUE fname)
{
#ifndef _WIN32
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (rb_group_member(st.st_gid)) return Qtrue;
#endif
return Qfalse;
}
如果指定的文件存在并且调用进程的有效组 ID 是该文件的所有者,则返回 true。 在 Windows 上返回 false。
file_name 可以是 IO 对象。
源
static VALUE
rb_file_identical_p(VALUE obj, VALUE fname1, VALUE fname2)
{
#ifndef _WIN32
struct stat st1, st2;
if (rb_stat(fname1, &st1) < 0) return Qfalse;
if (rb_stat(fname2, &st2) < 0) return Qfalse;
if (st1.st_dev != st2.st_dev) return Qfalse;
if (st1.st_ino != st2.st_ino) return Qfalse;
return Qtrue;
#else
extern VALUE rb_w32_file_identical_p(VALUE, VALUE);
return rb_w32_file_identical_p(fname1, fname2);
#endif
}
如果指定的文件相同,则返回 true。
file_1 和 file_2 可以是 IO 对象。
open("a", "w") {} p File.identical?("a", "a") #=> true p File.identical?("a", "./a") #=> true File.link("a", "b") p File.identical?("a", "b") #=> true File.symlink("a", "c") p File.identical?("a", "c") #=> true open("d", "w") {} p File.identical?("a", "d") #=> false
源
static VALUE
rb_file_owned_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
return RBOOL(st.st_uid == geteuid());
}
如果指定的文件存在并且调用进程的有效用户 ID 是该文件的所有者,则返回 true。
file_name 可以是 IO 对象。
源
static VALUE
rb_file_pipe_p(VALUE obj, VALUE fname)
{
#ifdef S_IFIFO
# ifndef S_ISFIFO
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
# endif
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISFIFO(st.st_mode)) return Qtrue;
#endif
return Qfalse;
}
如果 filepath 指向管道,则返回 true,否则返回 false
File.mkfifo('tmp/fifo') File.pipe?('tmp/fifo') # => true File.pipe?('t.txt') # => false
源
static VALUE
rb_file_readable_p(VALUE obj, VALUE fname)
{
return RBOOL(rb_eaccess(fname, R_OK) >= 0);
}
如果指定的文件可以被此进程的有效用户和组 ID 读取,则返回 true。 请参见 eaccess(3)。
请注意,某些操作系统级别的安全功能可能导致此方法返回 true,即使该文件对于有效用户/组来说是不可读的。
源
static VALUE
rb_file_readable_real_p(VALUE obj, VALUE fname)
{
return RBOOL(rb_access(fname, R_OK) >= 0);
}
如果指定的文件可以被此进程的真实用户和组 ID 读取,则返回 true。 请参见 access(3)。
请注意,某些操作系统级别的安全功能可能导致此方法返回 true,即使该文件对于真实用户/组来说是不可读的。
源
static VALUE
rb_file_sgid_p(VALUE obj, VALUE fname)
{
#ifdef S_ISGID
return check3rdbyte(fname, S_ISGID);
#else
return Qfalse;
#endif
}
如果指定的文件设置了 setgid 位,则返回 true。
file_name 可以是 IO 对象。
源
static VALUE
rb_file_suid_p(VALUE obj, VALUE fname)
{
#ifdef S_ISUID
return check3rdbyte(fname, S_ISUID);
#else
return Qfalse;
#endif
}
如果指定的文件设置了 setuid 位,则返回 true。
file_name 可以是 IO 对象。
源
static VALUE
rb_file_s_size(VALUE klass, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) {
int e = errno;
FilePathValue(fname);
rb_syserr_fail_path(e, fname);
}
return OFFT2NUM(st.st_size);
}
返回 file_name 的大小。
file_name 可以是 IO 对象。
源
static VALUE
rb_file_size_p(VALUE obj, VALUE fname)
{
struct stat st;
if (rb_stat(fname, &st) < 0) return Qnil;
if (st.st_size == 0) return Qnil;
return OFFT2NUM(st.st_size);
}
如果 file_name 不存在或大小为零,则返回 nil,否则返回文件的大小。
file_name 可以是 IO 对象。
源
static VALUE
rb_file_socket_p(VALUE obj, VALUE fname)
{
#ifndef S_ISSOCK
# ifdef _S_ISSOCK
# define S_ISSOCK(m) _S_ISSOCK(m)
# else
# ifdef _S_IFSOCK
# define S_ISSOCK(m) (((m) & S_IFMT) == _S_IFSOCK)
# else
# ifdef S_IFSOCK
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
# endif
# endif
# endif
#endif
#ifdef S_ISSOCK
struct stat st;
if (rb_stat(fname, &st) < 0) return Qfalse;
if (S_ISSOCK(st.st_mode)) return Qtrue;
#endif
return Qfalse;
}
如果 filepath 指向套接字,则返回 true,否则返回 false
require 'socket' File.socket?(Socket.new(:INET, :STREAM)) # => true File.socket?(File.new('t.txt')) # => false
源
static VALUE
rb_file_sticky_p(VALUE obj, VALUE fname)
{
#ifdef S_ISVTX
return check3rdbyte(fname, S_ISVTX);
#else
return Qfalse;
#endif
}
如果指定的文件设置了粘滞位,则返回 true。
file_name 可以是 IO 对象。
源
static VALUE
rb_file_symlink_p(VALUE obj, VALUE fname)
{
#ifndef S_ISLNK
# ifdef _S_ISLNK
# define S_ISLNK(m) _S_ISLNK(m)
# else
# ifdef _S_IFLNK
# define S_ISLNK(m) (((m) & S_IFMT) == _S_IFLNK)
# else
# ifdef S_IFLNK
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
# endif
# endif
# endif
#endif
#ifdef S_ISLNK
struct stat st;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
if (lstat_without_gvl(StringValueCStr(fname), &st) < 0) return Qfalse;
if (S_ISLNK(st.st_mode)) return Qtrue;
#endif
return Qfalse;
}
如果 filepath 指向符号链接,则返回 true,否则返回 false
symlink = File.symlink('t.txt', 'symlink') File.symlink?('symlink') # => true File.symlink?('t.txt') # => false
源
static VALUE
rb_file_world_readable_p(VALUE obj, VALUE fname)
{
#ifdef S_IROTH
struct stat st;
if (rb_stat(fname, &st) < 0) return Qnil;
if ((st.st_mode & (S_IROTH)) == S_IROTH) {
return UINT2NUM(st.st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
}
#endif
return Qnil;
}
如果其他人可读取 file_name,则返回一个整数,表示 file_name 的文件权限位。否则返回 nil。 这些位的含义取决于平台;在 Unix 系统上,请参阅 stat(2)。
file_name 可以是 IO 对象。
File.world_readable?("/etc/passwd") #=> 420 m = File.world_readable?("/etc/passwd") sprintf("%o", m) #=> "644"
源
static VALUE
rb_file_world_writable_p(VALUE obj, VALUE fname)
{
#ifdef S_IWOTH
struct stat st;
if (rb_stat(fname, &st) < 0) return Qnil;
if ((st.st_mode & (S_IWOTH)) == S_IWOTH) {
return UINT2NUM(st.st_mode & (S_IRUGO|S_IWUGO|S_IXUGO));
}
#endif
return Qnil;
}
如果其他人可写入 file_name,则返回一个整数,表示 file_name 的文件权限位。否则返回 nil。这些位的含义取决于平台;在 Unix 系统上,请参阅 stat(2)。
file_name 可以是 IO 对象。
File.world_writable?("/tmp") #=> 511 m = File.world_writable?("/tmp") sprintf("%o", m) #=> "777"
源
static VALUE
rb_file_writable_p(VALUE obj, VALUE fname)
{
return RBOOL(rb_eaccess(fname, W_OK) >= 0);
}
如果指定的文件可以被此进程的有效用户和组 ID 写入,则返回 true。 请参见 eaccess(3)。
请注意,某些操作系统级别的安全功能可能导致此方法返回 true,即使该文件对于有效用户/组来说是不可写的。
源
static VALUE
rb_file_writable_real_p(VALUE obj, VALUE fname)
{
return RBOOL(rb_access(fname, W_OK) >= 0);
}
如果指定的文件可以被此进程的真实用户和组 ID 写入,则返回 true。 请参见 access(3)。
请注意,某些操作系统级别的安全功能可能导致此方法返回 true,即使该文件对于真实用户/组来说是不可写的。