Class: File

Inherits:
IO show all
Defined in:
file.c

Overview

A File is an abstraction of any file object accessible by the program and is closely associated with class IO. File includes the methods of module FileTest as class methods, allowing you to write (for example) File.exist?("foo").

In the description of File methods, permission bits are a platform-specific set of bits that indicate permissions of a file. On Unix-based systems, permissions are viewed as a set of three octets, for the owner, the group, and the rest of the world. For each of these entities, permissions may be set to read, write, or execute the file:

The permission bits 0644 (in octal) would thus be interpreted as read/write for owner, and read-only for group and other. Higher-order bits may also be used to indicate the type of file (plain, directory, pipe, socket, and so on) and various other special features. If the permissions are for a directory, the meaning of the execute bit changes; when set the directory can be searched.

On non-Posix operating systems, there may be only the ability to make a file read-only or read-write. In this case, the remaining permission bits will be synthesized to resemble typical values. For instance, on Windows NT the default permission bits are 0644, which means read/write for owner, read-only for all others. The only change that can be made is to make the file read-only, which is reported as 0444.

Various constants for the methods in File can be found in File::Constants.

Defined Under Namespace

Modules: Constants Classes: Stat

Constant Summary collapse

Separator =

separates directory parts in path

separator
SEPARATOR =

separates directory parts in path

separator
ALT_SEPARATOR =

platform specific alternative separator

Qnil
PATH_SEPARATOR =

path list separator

rb_fstring_cstr(PATH_SEP)

Constants inherited from IO

IO::SEEK_CUR, IO::SEEK_DATA, IO::SEEK_END, IO::SEEK_HOLE, IO::SEEK_SET

Constants included from Constants

Constants::APPEND, Constants::BINARY, Constants::CREAT, Constants::DIRECT, Constants::DSYNC, Constants::EXCL, Constants::LOCK_EX, Constants::LOCK_NB, Constants::LOCK_SH, Constants::LOCK_UN, Constants::NOATIME, Constants::NOCTTY, Constants::NOFOLLOW, Constants::NONBLOCK, Constants::NULL, Constants::RDONLY, Constants::RDWR, Constants::RSYNC, Constants::SHARE_DELETE, Constants::SYNC, Constants::TMPFILE, Constants::TRUNC, Constants::WRONLY

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from IO

#<<, #advise, #autoclose=, #autoclose?, #binmode, #binmode?, binread, binwrite, #bytes, #chars, #close, #close_on_exec=, #close_on_exec?, #close_read, #close_write, #closed?, #codepoints, copy_stream, #each, #each_byte, #each_char, #each_codepoint, #each_line, #eof, #eof?, #external_encoding, #fcntl, #fdatasync, #fileno, #flush, for_fd, foreach, #fsync, #getbyte, #getc, #gets, #initialize_copy, #inspect, #internal_encoding, #ioctl, #isatty, #lineno, #lineno=, #lines, new, #pid, pipe, popen, #pos, #pos=, #pread, #print, #printf, #putc, #puts, #pwrite, read, #read, #readbyte, #readchar, #readline, readlines, #readlines, #readpartial, #reopen, #rewind, #seek, select, #set_encoding, #set_encoding_by_bom, #stat, #sync, #sync=, sysopen, #sysread, #sysseek, #syswrite, #tell, #to_io, try_convert, #tty?, #ungetbyte, #ungetc, #write, write

Methods included from Enumerable

#all?, #any?, #chain, #chunk, #chunk_while, #collect, #collect_concat, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #filter, #filter_map, #find, #find_all, #find_index, #first, #flat_map, #grep, #grep_v, #group_by, #include?, #inject, #lazy, #map, #max, #max_by, #member?, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reject, #reverse_each, #select, #slice_after, #slice_before, #slice_when, #sort, #sort_by, #sum, #take, #take_while, #tally, #to_a, #to_h, #uniq, #zip

Constructor Details

#new(filename, mode = "r"[, opt]) ⇒ File #new(filename[, mode [, perm]][, opt]) ⇒ File

Opens the file named by filename according to the given mode and returns a new File object.

See IO.new for a description of mode and opt.

If a file is being created, permission bits may be given in perm. These mode and permission bits are platform dependent; on Unix systems, see open(2) and chmod(2) man pages for details.

The new File object is buffered mode (or non-sync mode), unless filename is a tty. See IO#flush, IO#fsync, IO#fdatasync, and IO#sync= about sync mode.

Examples

f = File.new("testfile", "r")
f = File.new("newfile",  "w+")
f = File.new("newfile", File::CREAT|File::TRUNC|File::RDWR, 0644)

Overloads:

  • #new(filename, mode = "r"[, opt]) ⇒ File
  • #new(filename[, mode [, perm]][, opt]) ⇒ File


8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
# File 'io.c', line 8387

static VALUE
rb_file_initialize(int argc, VALUE *argv, VALUE io)
{
    if (RFILE(io)->fptr) {
	rb_raise(rb_eRuntimeError, "reinitializing File");
    }
    if (0 < argc && argc < 3) {
	VALUE fd = rb_check_to_int(argv[0]);

	if (!NIL_P(fd)) {
	    argv[0] = fd;
	    return rb_io_initialize(argc, argv, io);
	}
    }
    rb_open_file(argc, argv, io);

    return io;
}

Class Method Details

.absolute_path(file_name[, dir_string]) ⇒ Object

Converts a pathname to an absolute pathname. Relative paths are referenced from the current working directory of the process unless dir_string is given, in which case it will be used as the starting point. If the given pathname starts with a “~” it is NOT expanded, it is treated as a normal directory name.

File.absolute_path("~oracle/bin")       #=> "<relative_path>/~oracle/bin"


4113
4114
4115
4116
4117
# File 'file.c', line 4113

static VALUE
s_absolute_path(int c, const VALUE * v, VALUE _)
{
    return rb_file_s_absolute_path(c, v);
}

.absolute_path?(file_name) ⇒ Boolean

Returns true if file_name is an absolute path, and false otherwise.

File.absolute_path?("c:/foo")     #=> false (on Linux), true (on Windows)

Returns:

  • (Boolean)


4129
4130
4131
4132
4133
4134
4135
4136
# File 'file.c', line 4129

static VALUE
s_absolute_path_p(VALUE klass, VALUE fname)
{
    VALUE path = rb_get_path(fname);

    if (!rb_is_absolute_path(RSTRING_PTR(path))) return Qfalse;
    return Qtrue;
}

.atime(file_name) ⇒ Time

Returns the last access time for the named file as a Time object.

file_name can be an IO object.

File.atime("testfile")   #=> Wed Apr 09 08:51:48 CDT 2003

Returns:



2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
# File 'file.c', line 2311

static VALUE
rb_file_s_atime(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 stat_atime(&st);
}

.basename(file_name[, suffix]) ⇒ Object

Returns the last component of the filename given in file_name (after first stripping trailing separators), which can be formed using both File::SEPARATOR and File::ALT_SEPARATOR as the separator when File::ALT_SEPARATOR is not nil. If suffix is given and present at the end of file_name, it is removed. If suffix is “.*”, any extension will be removed.

File.basename("/home/gumby/work/ruby.rb")          #=> "ruby.rb"
File.basename("/home/gumby/work/ruby.rb", ".rb")   #=> "ruby"
File.basename("/home/gumby/work/ruby.rb", ".*")    #=> "ruby"


4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
# File 'file.c', line 4596

static VALUE
rb_file_s_basename(int argc, VALUE *argv, VALUE _)
{
    VALUE fname, fext, basename;
    const char *name, *p;
    long f, n;
    rb_encoding *enc;

    fext = Qnil;
    if (rb_check_arity(argc, 1, 2) == 2) {
	fext = argv[1];
	StringValue(fext);
	enc = check_path_encoding(fext);
    }
    fname = argv[0];
    FilePathStringValue(fname);
    if (NIL_P(fext) || !(enc = rb_enc_compatible(fname, fext))) {
	enc = rb_enc_get(fname);
	fext = Qnil;
    }
    if ((n = RSTRING_LEN(fname)) == 0 || !*(name = RSTRING_PTR(fname)))
	return rb_str_new_shared(fname);

    p = ruby_enc_find_basename(name, &f, &n, enc);
    if (n >= 0) {
	if (NIL_P(fext)) {
	    f = n;
	}
	else {
	    const char *fp;
	    fp = StringValueCStr(fext);
	    if (!(f = rmext(p, f, n, fp, RSTRING_LEN(fext), enc))) {
		f = n;
	    }
	    RB_GC_GUARD(fext);
	}
	if (f == RSTRING_LEN(fname)) return rb_str_new_shared(fname);
    }

    basename = rb_str_new(p, f);
    rb_enc_copy(basename, fname);
    return basename;
}

.birthtime(fname) ⇒ Object



2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
# File 'file.c', line 2466

RUBY_FUNC_EXPORTED VALUE
rb_file_s_birthtime(VALUE klass, VALUE fname)
{
    statx_data st;

    if (rb_statx(fname, &st, STATX_BTIME) < 0) {
	int e = errno;
	FilePathValue(fname);
	rb_syserr_fail_path(e, fname);
    }
    return statx_birthtime(&st, fname);
}

.blockdev?(file_name) ⇒ Boolean

Returns true if the named file is a block device.

file_name can be an IO object.

Returns:

  • (Boolean)


1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
# File 'file.c', line 1712

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;
}

.chardev?(file_name) ⇒ Boolean

Returns true if the named file is a character device.

file_name can be an IO object.

Returns:

  • (Boolean)


1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
# File 'file.c', line 1741

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;
}

.chmod(mode_int, file_name, ...) ⇒ Integer

Changes permission bits on the named file(s) to the bit pattern represented by mode_int. Actual effects are operating system dependent (see the beginning of this section). On Unix systems, see chmod(2) for details. Returns the number of files processed.

File.chmod(0644, "testfile", "out")   #=> 2

Returns:



2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
# File 'file.c', line 2556

static VALUE
rb_file_s_chmod(int argc, VALUE *argv, VALUE _)
{
    mode_t mode;

    apply2args(1);
    mode = NUM2MODET(*argv++);

    return apply2files(chmod_internal, argc, argv, &mode);
}

.chown(owner_int, group_int, file_name, ...) ⇒ Integer

Changes the owner and group of the named file(s) to the given numeric owner and group id’s. Only a process with superuser privileges may change the owner of a file. The current owner of a file may change the file’s group to any group to which the owner belongs. A nil or -1 owner or group id is ignored. Returns the number of files processed.

File.chown(nil, 100, "testfile")

Returns:



2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
# File 'file.c', line 2687

static VALUE
rb_file_s_chown(int argc, VALUE *argv, VALUE _)
{
    struct chown_args arg;

    apply2args(2);
    arg.owner = to_uid(*argv++);
    arg.group = to_gid(*argv++);

    return apply2files(chown_internal, argc, argv, &arg);
}

.ctime(file_name) ⇒ Time

Returns the change time for the named file (the time at which directory information about the file was changed, not the file itself).

file_name can be an IO object.

Note that on Windows (NTFS), returns creation time (birth time).

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

Returns:



2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
# File 'file.c', line 2412

static VALUE
rb_file_s_ctime(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 stat_ctime(&st);
}

.delete(file_name, ...) ⇒ Integer .unlink(file_name, ...) ⇒ Integer

Deletes the named files, returning the number of names passed as arguments. Raises an exception on any error. Since the underlying implementation relies on the unlink(2) system call, the type of exception raised depends on its error type (see linux.die.net/man/2/unlink) and has the form of e.g. Errno::ENOENT.

See also Dir::rmdir.

Overloads:



3158
3159
3160
3161
3162
# File 'file.c', line 3158

static VALUE
rb_file_s_unlink(int argc, VALUE *argv, VALUE klass)
{
    return apply2files(unlink_internal, argc, argv, 0);
}

.directory?(fname) ⇒ Boolean

call-seq:

File.directory?(file_name)   ->  true or false

Returns true if the named file is a directory, or a symlink that points at a directory, and false otherwise.

file_name can be an IO object.

File.directory?(".")

Returns:

  • (Boolean)


1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
# File 'file.c', line 1591

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;
}

.dirname(file_name) ⇒ Object

Returns all components of the filename given in file_name except the last one (after first stripping trailing separators). The filename can be formed using both File::SEPARATOR and File::ALT_SEPARATOR as the separator when File::ALT_SEPARATOR is not nil.

File.dirname("/home/gumby/work/ruby.rb")   #=> "/home/gumby/work"


4653
4654
4655
4656
4657
# File 'file.c', line 4653

static VALUE
rb_file_s_dirname(VALUE klass, VALUE fname)
{
    return rb_file_dirname(fname);
}

.zero?(file_name) ⇒ Boolean

Returns true if the named file exists and has a zero size.

file_name can be an IO object.

Returns:

  • (Boolean)


2018
2019
2020
2021
2022
2023
2024
2025
2026
# File 'file.c', line 2018

static VALUE
rb_file_zero_p(VALUE obj, VALUE fname)
{
    struct stat st;

    if (rb_stat(fname, &st) < 0) return Qfalse;
    if (st.st_size == 0) return Qtrue;
    return Qfalse;
}

.executable?(file_name) ⇒ Boolean

Returns true if the named file is executable by the effective user and group id of this process. See eaccess(3).

Windows does not support execute permissions separately from read permissions. On Windows, a file is only considered executable if it ends in .bat, .cmd, .com, or .exe.

Note that some OS-level security features may cause this to return true even though the file is not executable by the effective user/group.

Returns:

  • (Boolean)


1953
1954
1955
1956
1957
1958
# File 'file.c', line 1953

static VALUE
rb_file_executable_p(VALUE obj, VALUE fname)
{
    if (rb_eaccess(fname, X_OK) < 0) return Qfalse;
    return Qtrue;
}

.executable_real?(file_name) ⇒ Boolean

Returns true if the named file is executable by the real user and group id of this process. See access(3).

Windows does not support execute permissions separately from read permissions. On Windows, a file is only considered executable if it ends in .bat, .cmd, .com, or .exe.

Note that some OS-level security features may cause this to return true even though the file is not executable by the real user/group.

Returns:

  • (Boolean)


1975
1976
1977
1978
1979
1980
# File 'file.c', line 1975

static VALUE
rb_file_executable_real_p(VALUE obj, VALUE fname)
{
    if (rb_access(fname, X_OK) < 0) return Qfalse;
    return Qtrue;
}

.exist?(file_name) ⇒ Boolean

Return true if the named file exists.

file_name can be an IO object.

“file exists” means that stat() or fstat() system call is successful.

Returns:

  • (Boolean)


1767
1768
1769
1770
1771
1772
1773
1774
# File 'file.c', line 1767

static VALUE
rb_file_exist_p(VALUE obj, VALUE fname)
{
    struct stat st;

    if (rb_stat(fname, &st) < 0) return Qfalse;
    return Qtrue;
}

.exists?(file_name) ⇒ Boolean

Deprecated method. Don’t use.

Returns:

  • (Boolean)


1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
# File 'file.c', line 1782

static VALUE
rb_file_exists_p(VALUE obj, VALUE fname)
{
    const char *s = "FileTest#";
    if (obj == rb_mFileTest) {
	s = "FileTest.";
    }
    else if (obj == rb_cFile ||
	     (RB_TYPE_P(obj, T_CLASS) &&
	      RTEST(rb_class_inherited_p(obj, rb_cFile)))) {
	s = "File.";
    }
    rb_warning("%sexists? is a deprecated name, use %sexist? instead", s, s);
    return rb_file_exist_p(obj, fname);
}

.expand_path(file_name[, dir_string]) ⇒ Object

Converts a pathname to an absolute pathname. Relative paths are referenced from the current working directory of the process unless dir_string is given, in which case it will be used as the starting point. The given pathname may start with a “~”, which expands to the process owner’s home directory (the environment variable HOME must be set correctly). “~user” expands to the named user’s home directory.

File.expand_path("~oracle/bin")           #=> "/home/oracle/bin"

A simple example of using dir_string is as follows.

File.expand_path("ruby", "/usr/bin")      #=> "/usr/bin/ruby"

A more complex example which also resolves parent directory is as follows. Suppose we are in bin/mygem and want the absolute path of lib/mygem.rb.

File.expand_path("../../lib/mygem.rb", __FILE__)
#=> ".../path/to/project/lib/mygem.rb"

So first it resolves the parent of __FILE__, that is bin/, then go to the parent, the root of the project and appends lib/mygem.rb.



4080
4081
4082
4083
4084
# File 'file.c', line 4080

static VALUE
s_expand_path(int c, const VALUE * v, VALUE _)
{
    return rb_file_s_expand_path(c, v);
}

.extname(path) ⇒ String

Returns the extension (the portion of file name in path starting from the last period).

If path is a dotfile, or starts with a period, then the starting dot is not dealt with the start of the extension.

An empty string will also be returned when the period is the last character in path.

On Windows, trailing dots are truncated.

File.extname("test.rb")         #=> ".rb"
File.extname("a/b/d/test.rb")   #=> ".rb"
File.extname(".a/b/d/test.rb")  #=> ".rb"
File.extname("foo.")            #=> "" on Windows
File.extname("foo.")            #=> "." on non-Windows
File.extname("test")            #=> ""
File.extname(".profile")        #=> ""
File.extname(".profile.sh")     #=> ".sh"

Returns:



4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
# File 'file.c', line 4792

static VALUE
rb_file_s_extname(VALUE klass, VALUE fname)
{
    const char *name, *e;
    long len;
    VALUE extname;

    FilePathStringValue(fname);
    name = StringValueCStr(fname);
    len = RSTRING_LEN(fname);
    e = ruby_enc_find_extname(name, &len, rb_enc_get(fname));
    if (len < 1)
	return rb_str_new(0, 0);
    extname = rb_str_subseq(fname, e - name, len); /* keep the dot, too! */
    return extname;
}

.file?(file) ⇒ Boolean

Returns true if the named file exists and is a regular file.

file can be an IO object.

If the file argument is a symbolic link, it will resolve the symbolic link and use the file referenced by the link.

Returns:

  • (Boolean)


1998
1999
2000
2001
2002
2003
2004
2005
2006
# File 'file.c', line 1998

static VALUE
rb_file_file_p(VALUE obj, VALUE fname)
{
    struct stat st;

    if (rb_stat(fname, &st) < 0) return Qfalse;
    if (S_ISREG(st.st_mode)) return Qtrue;
    return Qfalse;
}

.fnmatch(pattern, path, [flags]) ⇒ Boolean .fnmatch?(pattern, path, [flags]) ⇒ Boolean

Returns true if path matches against pattern. The pattern is not a regular expression; instead it follows rules similar to shell filename globbing. It may contain the following metacharacters:

*

Matches any file. Can be restricted by other values in the glob. Equivalent to / .* /x in regexp.

*

Matches all files regular files

c*

Matches all files beginning with c

*c

Matches all files ending with c

*c*

Matches all files that have c in them (including at the beginning or end).

To match hidden files (that start with a . set the File::FNM_DOTMATCH flag.

**

Matches directories recursively or files expansively.

?

Matches any one character. Equivalent to /.{1}/ in regexp.

[set]

Matches any one character in set. Behaves exactly like character sets in Regexp, including set negation ([^a-z]).

\

Escapes the next metacharacter.

{a,b}

Matches pattern a and pattern b if File::FNM_EXTGLOB flag is enabled. Behaves like a Regexp union ((?:a|b)).

flags is a bitwise OR of the FNM_XXX constants. The same glob pattern and flags are used by Dir::glob.

Examples:

File.fnmatch('cat',       'cat')        #=> true  # match entire string
File.fnmatch('cat',       'category')   #=> false # only match partial string

File.fnmatch('c{at,ub}s', 'cats')                    #=> false # { } isn't supported by default
File.fnmatch('c{at,ub}s', 'cats', File::FNM_EXTGLOB) #=> true  # { } is supported on FNM_EXTGLOB

File.fnmatch('c?t',     'cat')          #=> true  # '?' match only 1 character
File.fnmatch('c??t',    'cat')          #=> false # ditto
File.fnmatch('c*',      'cats')         #=> true  # '*' match 0 or more characters
File.fnmatch('c*t',     'c/a/b/t')      #=> true  # ditto
File.fnmatch('ca[a-z]', 'cat')          #=> true  # inclusive bracket expression
File.fnmatch('ca[^t]',  'cat')          #=> false # exclusive bracket expression ('^' or '!')

File.fnmatch('cat', 'CAT')                     #=> false # case sensitive
File.fnmatch('cat', 'CAT', File::FNM_CASEFOLD) #=> true  # case insensitive
File.fnmatch('cat', 'CAT', File::FNM_SYSCASE)  #=> true or false # depends on the system default

File.fnmatch('?',   '/', File::FNM_PATHNAME)  #=> false # wildcard doesn't match '/' on FNM_PATHNAME
File.fnmatch('*',   '/', File::FNM_PATHNAME)  #=> false # ditto
File.fnmatch('[/]', '/', File::FNM_PATHNAME)  #=> false # ditto

File.fnmatch('\?',   '?')                       #=> true  # escaped wildcard becomes ordinary
File.fnmatch('\a',   'a')                       #=> true  # escaped ordinary remains ordinary
File.fnmatch('\a',   '\a', File::FNM_NOESCAPE)  #=> true  # FNM_NOESCAPE makes '\' ordinary
File.fnmatch('[\?]', '?')                       #=> true  # can escape inside bracket expression

File.fnmatch('*',   '.profile')                      #=> false # wildcard doesn't match leading
File.fnmatch('*',   '.profile', File::FNM_DOTMATCH)  #=> true  # period by default.
File.fnmatch('.*',  '.profile')                      #=> true

rbfiles = '**' '/' '*.rb' # you don't have to do like this. just write in single string.
File.fnmatch(rbfiles, 'main.rb')                    #=> false
File.fnmatch(rbfiles, './main.rb')                  #=> false
File.fnmatch(rbfiles, 'lib/song.rb')                #=> true
File.fnmatch('**.rb', 'main.rb')                    #=> true
File.fnmatch('**.rb', './main.rb')                  #=> false
File.fnmatch('**.rb', 'lib/song.rb')                #=> true
File.fnmatch('*',           'dave/.profile')                      #=> true

pattern = '*' '/' '*'
File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME)  #=> false
File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true

pattern = '**' '/' 'foo'
File.fnmatch(pattern, 'a/b/c/foo', File::FNM_PATHNAME)     #=> true
File.fnmatch(pattern, '/a/b/c/foo', File::FNM_PATHNAME)    #=> true
File.fnmatch(pattern, 'c:/a/b/c/foo', File::FNM_PATHNAME)  #=> true
File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME)    #=> false
File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true

Overloads:

  • .fnmatch(pattern, path, [flags]) ⇒ Boolean

    Returns:

    • (Boolean)
  • .fnmatch?(pattern, path, [flags]) ⇒ Boolean

    Returns:

    • (Boolean)


3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
# File 'dir.c', line 3222

static VALUE
file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
{
    VALUE pattern, path;
    VALUE rflags;
    int flags;

    if (rb_scan_args(argc, argv, "21", &pattern, &path, &rflags) == 3)
	flags = NUM2INT(rflags);
    else
	flags = 0;

    StringValueCStr(pattern);
    FilePathStringValue(path);

    if (flags & FNM_EXTGLOB) {
	struct brace_args args;

	args.value = path;
	args.flags = flags;
	if (ruby_brace_expand(RSTRING_PTR(pattern), flags, fnmatch_brace,
			      (VALUE)&args, rb_enc_get(pattern), pattern) > 0)
	    return Qtrue;
    }
    else {
	rb_encoding *enc = rb_enc_compatible(pattern, path);
	if (!enc) return Qfalse;
	if (fnmatch(RSTRING_PTR(pattern), enc, RSTRING_PTR(path), flags) == 0)
	    return Qtrue;
    }
    RB_GC_GUARD(pattern);

    return Qfalse;
}

.fnmatch(pattern, path, [flags]) ⇒ Boolean .fnmatch?(pattern, path, [flags]) ⇒ Boolean

Returns true if path matches against pattern. The pattern is not a regular expression; instead it follows rules similar to shell filename globbing. It may contain the following metacharacters:

*

Matches any file. Can be restricted by other values in the glob. Equivalent to / .* /x in regexp.

*

Matches all files regular files

c*

Matches all files beginning with c

*c

Matches all files ending with c

*c*

Matches all files that have c in them (including at the beginning or end).

To match hidden files (that start with a . set the File::FNM_DOTMATCH flag.

**

Matches directories recursively or files expansively.

?

Matches any one character. Equivalent to /.{1}/ in regexp.

[set]

Matches any one character in set. Behaves exactly like character sets in Regexp, including set negation ([^a-z]).

\

Escapes the next metacharacter.

{a,b}

Matches pattern a and pattern b if File::FNM_EXTGLOB flag is enabled. Behaves like a Regexp union ((?:a|b)).

flags is a bitwise OR of the FNM_XXX constants. The same glob pattern and flags are used by Dir::glob.

Examples:

File.fnmatch('cat',       'cat')        #=> true  # match entire string
File.fnmatch('cat',       'category')   #=> false # only match partial string

File.fnmatch('c{at,ub}s', 'cats')                    #=> false # { } isn't supported by default
File.fnmatch('c{at,ub}s', 'cats', File::FNM_EXTGLOB) #=> true  # { } is supported on FNM_EXTGLOB

File.fnmatch('c?t',     'cat')          #=> true  # '?' match only 1 character
File.fnmatch('c??t',    'cat')          #=> false # ditto
File.fnmatch('c*',      'cats')         #=> true  # '*' match 0 or more characters
File.fnmatch('c*t',     'c/a/b/t')      #=> true  # ditto
File.fnmatch('ca[a-z]', 'cat')          #=> true  # inclusive bracket expression
File.fnmatch('ca[^t]',  'cat')          #=> false # exclusive bracket expression ('^' or '!')

File.fnmatch('cat', 'CAT')                     #=> false # case sensitive
File.fnmatch('cat', 'CAT', File::FNM_CASEFOLD) #=> true  # case insensitive
File.fnmatch('cat', 'CAT', File::FNM_SYSCASE)  #=> true or false # depends on the system default

File.fnmatch('?',   '/', File::FNM_PATHNAME)  #=> false # wildcard doesn't match '/' on FNM_PATHNAME
File.fnmatch('*',   '/', File::FNM_PATHNAME)  #=> false # ditto
File.fnmatch('[/]', '/', File::FNM_PATHNAME)  #=> false # ditto

File.fnmatch('\?',   '?')                       #=> true  # escaped wildcard becomes ordinary
File.fnmatch('\a',   'a')                       #=> true  # escaped ordinary remains ordinary
File.fnmatch('\a',   '\a', File::FNM_NOESCAPE)  #=> true  # FNM_NOESCAPE makes '\' ordinary
File.fnmatch('[\?]', '?')                       #=> true  # can escape inside bracket expression

File.fnmatch('*',   '.profile')                      #=> false # wildcard doesn't match leading
File.fnmatch('*',   '.profile', File::FNM_DOTMATCH)  #=> true  # period by default.
File.fnmatch('.*',  '.profile')                      #=> true

rbfiles = '**' '/' '*.rb' # you don't have to do like this. just write in single string.
File.fnmatch(rbfiles, 'main.rb')                    #=> false
File.fnmatch(rbfiles, './main.rb')                  #=> false
File.fnmatch(rbfiles, 'lib/song.rb')                #=> true
File.fnmatch('**.rb', 'main.rb')                    #=> true
File.fnmatch('**.rb', './main.rb')                  #=> false
File.fnmatch('**.rb', 'lib/song.rb')                #=> true
File.fnmatch('*',           'dave/.profile')                      #=> true

pattern = '*' '/' '*'
File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME)  #=> false
File.fnmatch(pattern, 'dave/.profile', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true

pattern = '**' '/' 'foo'
File.fnmatch(pattern, 'a/b/c/foo', File::FNM_PATHNAME)     #=> true
File.fnmatch(pattern, '/a/b/c/foo', File::FNM_PATHNAME)    #=> true
File.fnmatch(pattern, 'c:/a/b/c/foo', File::FNM_PATHNAME)  #=> true
File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME)    #=> false
File.fnmatch(pattern, 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true

Overloads:

  • .fnmatch(pattern, path, [flags]) ⇒ Boolean

    Returns:

    • (Boolean)
  • .fnmatch?(pattern, path, [flags]) ⇒ Boolean

    Returns:

    • (Boolean)


3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
# File 'dir.c', line 3222

static VALUE
file_s_fnmatch(int argc, VALUE *argv, VALUE obj)
{
    VALUE pattern, path;
    VALUE rflags;
    int flags;

    if (rb_scan_args(argc, argv, "21", &pattern, &path, &rflags) == 3)
	flags = NUM2INT(rflags);
    else
	flags = 0;

    StringValueCStr(pattern);
    FilePathStringValue(path);

    if (flags & FNM_EXTGLOB) {
	struct brace_args args;

	args.value = path;
	args.flags = flags;
	if (ruby_brace_expand(RSTRING_PTR(pattern), flags, fnmatch_brace,
			      (VALUE)&args, rb_enc_get(pattern), pattern) > 0)
	    return Qtrue;
    }
    else {
	rb_encoding *enc = rb_enc_compatible(pattern, path);
	if (!enc) return Qfalse;
	if (fnmatch(RSTRING_PTR(pattern), enc, RSTRING_PTR(path), flags) == 0)
	    return Qtrue;
    }
    RB_GC_GUARD(pattern);

    return Qfalse;
}

.ftype(file_name) ⇒ String

Identifies the type of the named file; the return string is one of “file”, “directory”, “characterSpecial”, “blockSpecial”, “fifo”, “link”, “socket”, or “unknown”.

File.ftype("testfile")            #=> "file"
File.ftype("/dev/tty")            #=> "characterSpecial"
File.ftype("/tmp/.X11-unix/X0")   #=> "socket"

Returns:



2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
# File 'file.c', line 2285

static VALUE
rb_file_s_ftype(VALUE klass, VALUE fname)
{
    struct stat st;

    FilePathValue(fname);
    fname = rb_str_encode_ospath(fname);
    if (lstat_without_gvl(StringValueCStr(fname), &st) == -1) {
	rb_sys_fail_path(fname);
    }

    return rb_file_ftype(&st);
}

.grpowned?(file_name) ⇒ Boolean

Returns true if the named file exists and the effective group id of the calling process is the owner of the file. Returns false on Windows.

file_name can be an IO object.

Returns:

  • (Boolean)


2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
# File 'file.c', line 2090

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;
}

.identical?(file_1, file_2) ⇒ Boolean

Returns true if the named files are identical.

file_1 and file_2 can be an IO object.

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

Returns:

  • (Boolean)


2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
# File 'file.c', line 2190

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
}

.join(string, ...) ⇒ String

Returns a new string formed by joining the strings using "/".

File.join("usr", "mail", "gumby")   #=> "usr/mail/gumby"

Returns:



4928
4929
4930
4931
4932
# File 'file.c', line 4928

static VALUE
rb_file_s_join(VALUE klass, VALUE args)
{
    return rb_file_join(args);
}

.lchmod(mode_int, file_name, ...) ⇒ Integer

Equivalent to File::chmod, but does not follow symbolic links (so it will change the permissions associated with the link, not the file referenced by the link). Often not available.

Returns:



2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
# File 'file.c', line 2628

static VALUE
rb_file_s_lchmod(int argc, VALUE *argv, VALUE _)
{
    mode_t mode;

    apply2args(1);
    mode = NUM2MODET(*argv++);

    return apply2files(lchmod_internal, argc, argv, &mode);
}

.lchown(owner_int, group_int, file_name, ..) ⇒ Integer

Equivalent to File::chown, but does not follow symbolic links (so it will change the owner associated with the link, not the file referenced by the link). Often not available. Returns number of files in the argument list.

Returns:



2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
# File 'file.c', line 2759

static VALUE
rb_file_s_lchown(int argc, VALUE *argv, VALUE _)
{
    struct chown_args arg;

    apply2args(2);
    arg.owner = to_uid(*argv++);
    arg.group = to_gid(*argv++);

    return apply2files(lchown_internal, argc, argv, &arg);
}

Creates a new name for an existing file using a hard link. Will not overwrite new_name if it already exists (raising a subclass of SystemCallError). Not available on all platforms.

File.link("testfile", ".testfile")   #=> 0
IO.readlines(".testfile")[0]         #=> "This is line one\n"

Returns:

  • (0)


3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
# File 'file.c', line 3010

static VALUE
rb_file_s_link(VALUE klass, VALUE from, VALUE to)
{
    FilePathValue(from);
    FilePathValue(to);
    from = rb_str_encode_ospath(from);
    to = rb_str_encode_ospath(to);

    if (link(StringValueCStr(from), StringValueCStr(to)) < 0) {
	sys_fail2(from, to);
    }
    return INT2FIX(0);
}

.lstat(file_name) ⇒ Object

Same as File::stat, but does not follow the last symbolic link. Instead, reports on the link itself.

File.symlink("testfile", "link2test")   #=> 0
File.stat("testfile").size              #=> 66
File.lstat("link2test").size            #=> 8
File.stat("link2test").size             #=> 66


1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
# File 'file.c', line 1367

static VALUE
rb_file_s_lstat(VALUE klass, VALUE fname)
{
#ifdef HAVE_LSTAT
    struct stat st;

    FilePathValue(fname);
    fname = rb_str_encode_ospath(fname);
    if (lstat_without_gvl(StringValueCStr(fname), &st) == -1) {
	rb_sys_fail_path(fname);
    }
    return rb_stat_new(&st);
#else
    return rb_file_s_stat(klass, fname);
#endif
}

.lutime(atime, mtime, file_name, ...) ⇒ Integer

Sets the access and modification times of each named file to the first two arguments. If a file is a symlink, this method acts upon the link itself as opposed to its referent; for the inverse behavior, see File.utime. Returns the number of file names in the argument list.

Returns:



2956
2957
2958
2959
2960
# File 'file.c', line 2956

static VALUE
rb_file_s_lutime(int argc, VALUE *argv, VALUE _)
{
    return utime_internal_i(argc, argv, TRUE);
}

.mkfifo(file_name, mode = 0666) ⇒ 0

Creates a FIFO special file with name file_name. mode specifies the FIFO’s permissions. It is modified by the process’s umask in the usual way: the permissions of the created file are (mode & ~umask).

Returns:

  • (0)


6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
# File 'file.c', line 6071

static VALUE
rb_file_s_mkfifo(int argc, VALUE *argv, VALUE _)
{
    VALUE path;
    struct mkfifo_arg ma;

    ma.mode = 0666;
    rb_check_arity(argc, 1, 2);
    if (argc > 1) {
	ma.mode = NUM2MODET(argv[1]);
    }
    path = argv[0];
    FilePathValue(path);
    path = rb_str_encode_ospath(path);
    ma.path = RSTRING_PTR(path);
    if (rb_thread_call_without_gvl(nogvl_mkfifo, &ma, RUBY_UBF_IO, 0)) {
	rb_sys_fail_path(path);
    }
    return INT2FIX(0);
}

.mtime(file_name) ⇒ Time

Returns the modification time for the named file as a Time object.

file_name can be an IO object.

File.mtime("testfile")   #=> Tue Apr 08 12:58:04 CDT 2003

Returns:



2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
# File 'file.c', line 2360

static VALUE
rb_file_s_mtime(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 stat_mtime(&st);
}

.open(*args) ⇒ Object

call-seq:

IO.open(fd, mode="r" [, opt])                -> io
IO.open(fd, mode="r" [, opt]) {|io| block }  -> obj

With no associated block, IO.open is a synonym for IO.new. If the optional code block is given, it will be passed io as an argument, and the IO object will automatically be closed when the block terminates. In this instance, IO.open returns the value of the block.

See IO.new for a description of the fd, mode and opt parameters.



7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
# File 'io.c', line 7042

static VALUE
rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE io = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);

    if (rb_block_given_p()) {
	return rb_ensure(rb_yield, io, io_close, io);
    }

    return io;
}

.owned?(file_name) ⇒ Boolean

Returns true if the named file exists and the effective used id of the calling process is the owner of the file.

file_name can be an IO object.

Returns:

  • (Boolean)


2059
2060
2061
2062
2063
2064
2065
2066
2067
# File 'file.c', line 2059

static VALUE
rb_file_owned_p(VALUE obj, VALUE fname)
{
    struct stat st;

    if (rb_stat(fname, &st) < 0) return Qfalse;
    if (st.st_uid == geteuid()) return Qtrue;
    return Qfalse;
}

.path(path) ⇒ String

Returns the string representation of the path

File.path("/dev/null")          #=> "/dev/null"
File.path(Pathname.new("/tmp")) #=> "/tmp"

Returns:



4820
4821
4822
4823
4824
# File 'file.c', line 4820

static VALUE
rb_file_s_path(VALUE klass, VALUE fname)
{
    return rb_get_path(fname);
}

.pipe?(file_name) ⇒ Boolean

Returns true if the named file is a pipe.

file_name can be an IO object.

Returns:

  • (Boolean)


1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
# File 'file.c', line 1614

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;
}

.readable?(file_name) ⇒ Boolean

Returns true if the named file is readable by the effective user and group id of this process. See eaccess(3).

Note that some OS-level security features may cause this to return true even though the file is not readable by the effective user/group.

Returns:

  • (Boolean)


1809
1810
1811
1812
1813
1814
# File 'file.c', line 1809

static VALUE
rb_file_readable_p(VALUE obj, VALUE fname)
{
    if (rb_eaccess(fname, R_OK) < 0) return Qfalse;
    return Qtrue;
}

.readable_real?(file_name) ⇒ Boolean

Returns true if the named file is readable by the real user and group id of this process. See access(3).

Note that some OS-level security features may cause this to return true even though the file is not readable by the real user/group.

Returns:

  • (Boolean)


1827
1828
1829
1830
1831
1832
# File 'file.c', line 1827

static VALUE
rb_file_readable_real_p(VALUE obj, VALUE fname)
{
    if (rb_access(fname, R_OK) < 0) return Qfalse;
    return Qtrue;
}

Returns the name of the file referenced by the given link. Not available on all platforms.

File.symlink("testfile", "link2test")   #=> 0
File.readlink("link2test")              #=> "testfile"


3069
3070
3071
3072
3073
# File 'file.c', line 3069

static VALUE
rb_file_s_readlink(VALUE klass, VALUE path)
{
    return rb_readlink(path, rb_filesystem_encoding());
}

.realdirpath(pathname[, dir_string]) ⇒ Object

Returns the real (absolute) pathname of pathname in the actual filesystem.

The real pathname doesn't contain symlinks or useless dots.

If _dir_string_ is given, it is used as a base directory
for interpreting relative pathname instead of the current directory.

The last component of the real pathname can be nonexistent.


4471
4472
4473
4474
4475
4476
4477
4478
# File 'file.c', line 4471

static VALUE
rb_file_s_realdirpath(int argc, VALUE *argv, VALUE klass)
{
    VALUE basedir = (rb_check_arity(argc, 1, 2) > 1) ? argv[1] : Qnil;
    VALUE path = argv[0];
    FilePathValue(path);
    return rb_realpath_internal(basedir, path, 0);
}

.realpath(pathname[, dir_string]) ⇒ Object

Returns the real (absolute) pathname of pathname in the actual

filesystem not containing symlinks or useless dots.

If _dir_string_ is given, it is used as a base directory
for interpreting relative pathname instead of the current directory.

All components of the pathname must exist when this method is
called.


4450
4451
4452
4453
4454
4455
4456
4457
# File 'file.c', line 4450

static VALUE
rb_file_s_realpath(int argc, VALUE *argv, VALUE klass)
{
    VALUE basedir = (rb_check_arity(argc, 1, 2) > 1) ? argv[1] : Qnil;
    VALUE path = argv[0];
    FilePathValue(path);
    return rb_realpath_internal(basedir, path, 1);
}

.rename(old_name, new_name) ⇒ 0

Renames the given file to the new name. Raises a SystemCallError if the file cannot be renamed.

File.rename("afile", "afile.bak")   #=> 0

Returns:

  • (0)


3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
# File 'file.c', line 3187

static VALUE
rb_file_s_rename(VALUE klass, VALUE from, VALUE to)
{
    struct rename_args ra;
    VALUE f, t;

    FilePathValue(from);
    FilePathValue(to);
    f = rb_str_encode_ospath(from);
    t = rb_str_encode_ospath(to);
    ra.src = StringValueCStr(f);
    ra.dst = StringValueCStr(t);
#if defined __CYGWIN__
    errno = 0;
#endif
    if ((int)(VALUE)rb_thread_call_without_gvl(no_gvl_rename, &ra,
					 RUBY_UBF_IO, 0) < 0) {
	int e = errno;
#if defined DOSISH
	switch (e) {
	  case EEXIST:
	    if (chmod(ra.dst, 0666) == 0 &&
		unlink(ra.dst) == 0 &&
		rename(ra.src, ra.dst) == 0)
		return INT2FIX(0);
	}
#endif
	syserr_fail2(e, from, to);
    }

    return INT2FIX(0);
}

.setgid?(file_name) ⇒ Boolean

Returns true if the named file has the setgid bit set.

file_name can be an IO object.

Returns:

  • (Boolean)


2142
2143
2144
2145
2146
2147
2148
2149
2150
# File 'file.c', line 2142

static VALUE
rb_file_sgid_p(VALUE obj, VALUE fname)
{
#ifdef S_ISGID
    return check3rdbyte(fname, S_ISGID);
#else
    return Qfalse;
#endif
}

.setuid?(file_name) ⇒ Boolean

Returns true if the named file has the setuid bit set.

file_name can be an IO object.

Returns:

  • (Boolean)


2123
2124
2125
2126
2127
2128
2129
2130
2131
# File 'file.c', line 2123

static VALUE
rb_file_suid_p(VALUE obj, VALUE fname)
{
#ifdef S_ISUID
    return check3rdbyte(fname, S_ISUID);
#else
    return Qfalse;
#endif
}

.size(file_name) ⇒ Integer

Returns the size of file_name.

file_name can be an IO object.

Returns:



2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
# File 'file.c', line 2216

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);
}

.size?(file_name) ⇒ Integer?

Returns nil if file_name doesn’t exist or has zero size, the size of the file otherwise.

file_name can be an IO object.

Returns:



2038
2039
2040
2041
2042
2043
2044
2045
2046
# File 'file.c', line 2038

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);
}

.socket?(file_name) ⇒ Boolean

Returns true if the named file is a socket.

file_name can be an IO object.

Returns:

  • (Boolean)


1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
# File 'file.c', line 1676

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;
}

.split(file_name) ⇒ Array

Splits the given string into a directory and a file component and returns them in a two-element array. See also File::dirname and File::basename.

File.split("/home/gumby/.profile")   #=> ["/home/gumby", ".profile"]

Returns:



4837
4838
4839
4840
4841
4842
# File 'file.c', line 4837

static VALUE
rb_file_s_split(VALUE klass, VALUE path)
{
    FilePathStringValue(path);		/* get rid of converting twice */
    return rb_assoc_new(rb_file_dirname(path), rb_file_s_basename(1,&path,Qundef));
}

.stat(file_name) ⇒ Object

Returns a File::Stat object for the named file (see File::Stat).

File.stat("testfile").mtime   #=> Tue Apr 08 12:58:04 CDT 2003


1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
# File 'file.c', line 1291

static VALUE
rb_file_s_stat(VALUE klass, VALUE fname)
{
    struct stat st;

    FilePathValue(fname);
    fname = rb_str_encode_ospath(fname);
    if (stat_without_gvl(RSTRING_PTR(fname), &st) < 0) {
	rb_sys_fail_path(fname);
    }
    return rb_stat_new(&st);
}

.sticky?(file_name) ⇒ Boolean

Returns true if the named file has the sticky bit set.

file_name can be an IO object.

Returns:

  • (Boolean)


2161
2162
2163
2164
2165
2166
2167
2168
2169
# File 'file.c', line 2161

static VALUE
rb_file_sticky_p(VALUE obj, VALUE fname)
{
#ifdef S_ISVTX
    return check3rdbyte(fname, S_ISVTX);
#else
    return Qnil;
#endif
}

Creates a symbolic link called new_name for the existing file old_name. Raises a NotImplemented exception on platforms that do not support symbolic links.

File.symlink("testfile", "link2test")   #=> 0

Returns:

  • (0)


3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
# File 'file.c', line 3040

static VALUE
rb_file_s_symlink(VALUE klass, VALUE from, VALUE to)
{
    FilePathValue(from);
    FilePathValue(to);
    from = rb_str_encode_ospath(from);
    to = rb_str_encode_ospath(to);

    if (symlink(StringValueCStr(from), StringValueCStr(to)) < 0) {
	sys_fail2(from, to);
    }
    return INT2FIX(0);
}

.symlink?(file_name) ⇒ Boolean

Returns true if the named file is a symbolic link.

Returns:

  • (Boolean)


1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
# File 'file.c', line 1638

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;
}

.truncate(file_name, integer) ⇒ 0

Truncates the file file_name to be at most integer bytes long. Not available on all platforms.

f = File.new("out", "w")
f.write("1234567890")     #=> 10
f.close                   #=> nil
File.truncate("out", 5)   #=> 0
File.size("out")          #=> 5

Returns:

  • (0)


4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
# File 'file.c', line 4986

static VALUE
rb_file_s_truncate(VALUE klass, VALUE path, VALUE len)
{
    struct truncate_arg ta;
    int r;

    ta.pos = NUM2POS(len);
    FilePathValue(path);
    path = rb_str_encode_ospath(path);
    ta.path = StringValueCStr(path);

    r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_truncate, &ta,
						RUBY_UBF_IO, NULL);
    if (r < 0)
	rb_sys_fail_path(path);
    return INT2FIX(0);
#undef NUM2POS
}

.umaskInteger .umask(integer) ⇒ Integer

Returns the current umask value for this process. If the optional argument is given, set the umask to that value and return the previous value. Umask values are subtracted from the default permissions, so a umask of 0222 would make a file read-only for everyone.

File.umask(0006)   #=> 18
File.umask         #=> 6

Overloads:



3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
# File 'file.c', line 3235

static VALUE
rb_file_s_umask(int argc, VALUE *argv, VALUE _)
{
    mode_t omask = 0;

    switch (argc) {
      case 0:
	omask = umask(0);
	umask(omask);
        break;
      case 1:
	omask = umask(NUM2MODET(argv[0]));
        break;
      default:
        rb_error_arity(argc, 0, 1);
    }
    return MODET2NUM(omask);
}

Deletes the named files, returning the number of names passed as arguments. Raises an exception on any error. Since the underlying implementation relies on the unlink(2) system call, the type of exception raised depends on its error type (see linux.die.net/man/2/unlink) and has the form of e.g. Errno::ENOENT.

See also Dir::rmdir.

Overloads:



3158
3159
3160
3161
3162
# File 'file.c', line 3158

static VALUE
rb_file_s_unlink(int argc, VALUE *argv, VALUE klass)
{
    return apply2files(unlink_internal, argc, argv, 0);
}

.utime(atime, mtime, file_name, ...) ⇒ Integer

Sets the access and modification times of each named file to the first two arguments. If a file is a symlink, this method acts upon its referent rather than the link itself; for the inverse behavior see File.lutime. Returns the number of file names in the argument list.

Returns:



2937
2938
2939
2940
2941
# File 'file.c', line 2937

static VALUE
rb_file_s_utime(int argc, VALUE *argv, VALUE _)
{
    return utime_internal_i(argc, argv, FALSE);
}

.world_readable?(file_name) ⇒ Integer?

If file_name is readable by others, returns an integer representing the file permission bits of file_name. Returns nil otherwise. The meaning of the bits is platform dependent; on Unix systems, see stat(2).

file_name can be an IO object.

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

Returns:



1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
# File 'file.c', line 1858

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;
}

.world_writable?(file_name) ⇒ Integer?

If file_name is writable by others, returns an integer representing the file permission bits of file_name. Returns nil otherwise. The meaning of the bits is platform dependent; on Unix systems, see stat(2).

file_name can be an IO object.

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

Returns:



1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
# File 'file.c', line 1924

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;
}

.writable?(file_name) ⇒ Boolean

Returns true if the named file is writable by the effective user and group id of this process. See eaccess(3).

Note that some OS-level security features may cause this to return true even though the file is not writable by the effective user/group.

Returns:

  • (Boolean)


1883
1884
1885
1886
1887
1888
# File 'file.c', line 1883

static VALUE
rb_file_writable_p(VALUE obj, VALUE fname)
{
    if (rb_eaccess(fname, W_OK) < 0) return Qfalse;
    return Qtrue;
}

.writable_real?(file_name) ⇒ Boolean

Returns true if the named file is writable by the real user and group id of this process. See access(3).

Note that some OS-level security features may cause this to return true even though the file is not writable by the real user/group.

Returns:

  • (Boolean)


1901
1902
1903
1904
1905
1906
# File 'file.c', line 1901

static VALUE
rb_file_writable_real_p(VALUE obj, VALUE fname)
{
    if (rb_access(fname, W_OK) < 0) return Qfalse;
    return Qtrue;
}

.zero?(file_name) ⇒ Boolean

Returns true if the named file exists and has a zero size.

file_name can be an IO object.

Returns:

  • (Boolean)


2018
2019
2020
2021
2022
2023
2024
2025
2026
# File 'file.c', line 2018

static VALUE
rb_file_zero_p(VALUE obj, VALUE fname)
{
    struct stat st;

    if (rb_stat(fname, &st) < 0) return Qfalse;
    if (st.st_size == 0) return Qtrue;
    return Qfalse;
}

Instance Method Details

#atimeTime

Returns the last access time (a Time object) for file, or epoch if file has not been accessed.

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

Returns:



2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
# File 'file.c', line 2335

static VALUE
rb_file_atime(VALUE obj)
{
    rb_io_t *fptr;
    struct stat st;

    GetOpenFile(obj, fptr);
    if (fstat(fptr->fd, &st) == -1) {
	rb_sys_fail_path(fptr->pathv);
    }
    return stat_atime(&st);
}

#birthtimeTime

Returns the birth time for file.

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

If the platform doesn’t have birthtime, raises NotImplementedError.

Returns:



2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
# File 'file.c', line 2495

static VALUE
rb_file_birthtime(VALUE obj)
{
    rb_io_t *fptr;
    statx_data st;

    GetOpenFile(obj, fptr);
    if (fstatx_without_gvl(fptr->fd, &st, STATX_BTIME) == -1) {
	rb_sys_fail_path(fptr->pathv);
    }
    return statx_birthtime(&st, fptr->pathv);
}

#chmod(mode_int) ⇒ 0

Changes permission bits on file to the bit pattern represented by mode_int. Actual effects are platform dependent; on Unix systems, see chmod(2) for details. Follows symbolic links. Also see File#lchmod.

f = File.new("out", "w");
f.chmod(0644)   #=> 0

Returns:

  • (0)


2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
# File 'file.c', line 2580

static VALUE
rb_file_chmod(VALUE obj, VALUE vmode)
{
    rb_io_t *fptr;
    mode_t mode;
#if !defined HAVE_FCHMOD || !HAVE_FCHMOD
    VALUE path;
#endif

    mode = NUM2MODET(vmode);

    GetOpenFile(obj, fptr);
#ifdef HAVE_FCHMOD
    if (fchmod(fptr->fd, mode) == -1) {
	if (HAVE_FCHMOD || errno != ENOSYS)
	    rb_sys_fail_path(fptr->pathv);
    }
    else {
	if (!HAVE_FCHMOD) return INT2FIX(0);
    }
#endif
#if !defined HAVE_FCHMOD || !HAVE_FCHMOD
    if (NIL_P(fptr->pathv)) return Qnil;
    path = rb_str_encode_ospath(fptr->pathv);
    if (chmod(RSTRING_PTR(path), mode) == -1)
	rb_sys_fail_path(fptr->pathv);
#endif

    return INT2FIX(0);
}

#chown(owner_int, group_int) ⇒ 0

Changes the owner and group of file to the given numeric owner and group id’s. Only a process with superuser privileges may change the owner of a file. The current owner of a file may change the file’s group to any group to which the owner belongs. A nil or -1 owner or group id is ignored. Follows symbolic links. See also File#lchown.

File.new("testfile").chown(502, 1000)

Returns:

  • (0)


2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
# File 'file.c', line 2714

static VALUE
rb_file_chown(VALUE obj, VALUE owner, VALUE group)
{
    rb_io_t *fptr;
    rb_uid_t o;
    rb_gid_t g;
#ifndef HAVE_FCHOWN
    VALUE path;
#endif

    o = to_uid(owner);
    g = to_gid(group);
    GetOpenFile(obj, fptr);
#ifndef HAVE_FCHOWN
    if (NIL_P(fptr->pathv)) return Qnil;
    path = rb_str_encode_ospath(fptr->pathv);
    if (chown(RSTRING_PTR(path), o, g) == -1)
	rb_sys_fail_path(fptr->pathv);
#else
    if (fchown(fptr->fd, o, g) == -1)
	rb_sys_fail_path(fptr->pathv);
#endif

    return INT2FIX(0);
}

#ctimeTime

Returns the change time for file (that is, the time directory information about the file was changed, not the file itself).

Note that on Windows (NTFS), returns creation time (birth time).

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

Returns:



2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
# File 'file.c', line 2438

static VALUE
rb_file_ctime(VALUE obj)
{
    rb_io_t *fptr;
    struct stat st;

    GetOpenFile(obj, fptr);
    if (fstat(fptr->fd, &st) == -1) {
	rb_sys_fail_path(fptr->pathv);
    }
    return stat_ctime(&st);
}

#flock(locking_constant) ⇒ 0, false

Locks or unlocks a file according to locking_constant (a logical or of the values in the table below). Returns false if File::LOCK_NB is specified and the operation would otherwise have blocked. Not available on all platforms.

Locking constants (in class File):

LOCK_EX   | Exclusive lock. Only one process may hold an
          | exclusive lock for a given file at a time.
----------+------------------------------------------------
LOCK_NB   | Don't block when locking. May be combined
          | with other lock options using logical or.
----------+------------------------------------------------
LOCK_SH   | Shared lock. Multiple processes may each hold a
          | shared lock for a given file at the same time.
----------+------------------------------------------------
LOCK_UN   | Unlock.

Example:

# update a counter using write lock
# don't use "w" because it truncates the file before lock.
File.open("counter", File::RDWR|File::CREAT, 0644) {|f|
  f.flock(File::LOCK_EX)
  value = f.read.to_i + 1
  f.rewind
  f.write("#{value}\n")
  f.flush
  f.truncate(f.pos)
}

# read the counter using read lock
File.open("counter", "r") {|f|
  f.flock(File::LOCK_SH)
  p f.read
}

Returns:

  • (0, false)


5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
# File 'file.c', line 5147

static VALUE
rb_file_flock(VALUE obj, VALUE operation)
{
    rb_io_t *fptr;
    int op[2], op1;
    struct timeval time;

    op[1] = op1 = NUM2INT(operation);
    GetOpenFile(obj, fptr);
    op[0] = fptr->fd;

    if (fptr->mode & FMODE_WRITABLE) {
	rb_io_flush_raw(obj, 0);
    }
    while ((int)rb_thread_io_blocking_region(rb_thread_flock, op, fptr->fd) < 0) {
	int e = errno;
	switch (e) {
	  case EAGAIN:
	  case EACCES:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
	  case EWOULDBLOCK:
#endif
	    if (op1 & LOCK_NB) return Qfalse;

	    time.tv_sec = 0;
	    time.tv_usec = 100 * 1000;	/* 0.1 sec */
	    rb_thread_wait_for(time);
	    rb_io_check_closed(fptr);
	    continue;

	  case EINTR:
#if defined(ERESTART)
	  case ERESTART:
#endif
	    break;

	  default:
	    rb_syserr_fail_path(e, fptr->pathv);
	}
    }
    return INT2FIX(0);
}

#lstatObject

Same as IO#stat, but does not follow the last symbolic link. Instead, reports on the link itself.

File.symlink("testfile", "link2test")   #=> 0
File.stat("testfile").size              #=> 66
f = File.new("link2test")
f.lstat.size                            #=> 8
f.stat.size                             #=> 66


1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
# File 'file.c', line 1398

static VALUE
rb_file_lstat(VALUE obj)
{
#ifdef HAVE_LSTAT
    rb_io_t *fptr;
    struct stat st;
    VALUE path;

    GetOpenFile(obj, fptr);
    if (NIL_P(fptr->pathv)) return Qnil;
    path = rb_str_encode_ospath(fptr->pathv);
    if (lstat_without_gvl(RSTRING_PTR(path), &st) == -1) {
	rb_sys_fail_path(fptr->pathv);
    }
    return rb_stat_new(&st);
#else
    return rb_io_stat(obj);
#endif
}

#mtimeTime

Returns the modification time for file.

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

Returns:



2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
# File 'file.c', line 2383

static VALUE
rb_file_mtime(VALUE obj)
{
    rb_io_t *fptr;
    struct stat st;

    GetOpenFile(obj, fptr);
    if (fstat(fptr->fd, &st) == -1) {
	rb_sys_fail_path(fptr->pathv);
    }
    return stat_mtime(&st);
}

#pathObject #to_pathObject

Returns the pathname used to create file as a string. Does not normalize the name.

The pathname may not point to the file corresponding to file. For instance, the pathname becomes void when the file has been moved or deleted.

This method raises IOError for a file created using File::Constants::TMPFILE because they don’t have a pathname.

File.new("testfile").path               #=> "testfile"
File.new("/tmp/../tmp/xxx", "w").path   #=> "/tmp/../tmp/xxx"


465
466
467
468
469
470
471
472
473
474
475
476
477
478
# File 'file.c', line 465

static VALUE
rb_file_path(VALUE obj)
{
    rb_io_t *fptr;

    fptr = RFILE(rb_io_taint_check(obj))->fptr;
    rb_io_check_initialized(fptr);

    if (NIL_P(fptr->pathv)) {
        rb_raise(rb_eIOError, "File is unnamed (TMPFILE?)");
    }

    return rb_str_dup(fptr->pathv);
}

#sizeInteger

Returns the size of file in bytes.

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

Returns:



2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
# File 'file.c', line 2521

static VALUE
rb_file_size(VALUE obj)
{
    rb_io_t *fptr;
    struct stat st;

    GetOpenFile(obj, fptr);
    if (fptr->mode & FMODE_WRITABLE) {
	rb_io_flush_raw(obj, 0);
    }
    if (fstat(fptr->fd, &st) == -1) {
	rb_sys_fail_path(fptr->pathv);
    }
    return OFFT2NUM(st.st_size);
}

#pathObject #to_pathObject

Returns the pathname used to create file as a string. Does not normalize the name.

The pathname may not point to the file corresponding to file. For instance, the pathname becomes void when the file has been moved or deleted.

This method raises IOError for a file created using File::Constants::TMPFILE because they don’t have a pathname.

File.new("testfile").path               #=> "testfile"
File.new("/tmp/../tmp/xxx", "w").path   #=> "/tmp/../tmp/xxx"


465
466
467
468
469
470
471
472
473
474
475
476
477
478
# File 'file.c', line 465

static VALUE
rb_file_path(VALUE obj)
{
    rb_io_t *fptr;

    fptr = RFILE(rb_io_taint_check(obj))->fptr;
    rb_io_check_initialized(fptr);

    if (NIL_P(fptr->pathv)) {
        rb_raise(rb_eIOError, "File is unnamed (TMPFILE?)");
    }

    return rb_str_dup(fptr->pathv);
}

#truncate(integer) ⇒ 0

Truncates file to at most integer bytes. The file must be opened for writing. Not available on all platforms.

f = File.new("out", "w")
f.syswrite("1234567890")   #=> 10
f.truncate(5)              #=> 0
f.close()                  #=> nil
File.size("out")           #=> 5

Returns:

  • (0)


5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
# File 'file.c', line 5046

static VALUE
rb_file_truncate(VALUE obj, VALUE len)
{
    rb_io_t *fptr;
    struct ftruncate_arg fa;

    fa.pos = NUM2POS(len);
    GetOpenFile(obj, fptr);
    if (!(fptr->mode & FMODE_WRITABLE)) {
	rb_raise(rb_eIOError, "not opened for writing");
    }
    rb_io_flush_raw(obj, 0);
    fa.fd = fptr->fd;
    if ((int)rb_thread_io_blocking_region(nogvl_ftruncate, &fa, fa.fd) < 0) {
	rb_sys_fail_path(fptr->pathv);
    }
    return INT2FIX(0);
#undef NUM2POS
}