類別 File

File 物件是底層平台中檔案的表示。

類別 File 延伸模組 FileTest,支援單例方法,例如 File.exist?

關於範例

這裡的許多範例使用這些變數

# English text with newlines.
text = <<~EOT
  First line
  Second line

  Fourth line
  Fifth line
EOT

# Russian text.
russian = "\u{442 435 441 442}" # => "тест"

# Binary data.
data = "\u9990\u9991\u9992\u9993\u9994"

# Text file.
File.write('t.txt', text)

# File with Russian text.
File.write('t.rus', russian)

# File with binary data.
f = File.new('t.dat', 'wb:UTF-16')
f.write(data)
f.close

存取模式

方法 File.newFile.open 各為指定檔案路徑建立一個 File 物件。

字串存取模式

方法 File.newFile.open 各可以接受字串引數 mode,其中

讀取/寫入模式

讀取/寫入 mode 決定

這些表格摘要

Read/Write Modes for Existing File

|------|-----------|----------|----------|----------|-----------|
| R/W  | Initial   |          | Initial  |          | Initial   |
| Mode | Truncate? |  Read    | Read Pos |  Write   | Write Pos |
|------|-----------|----------|----------|----------|-----------|
| 'r'  |    No     | Anywhere |    0     |   Error  |     -     |
| 'w'  |    Yes    |   Error  |    -     | Anywhere |     0     |
| 'a'  |    No     |   Error  |    -     | End only |    End    |
| 'r+' |    No     | Anywhere |    0     | Anywhere |     0     |
| 'w+' |    Yes    | Anywhere |    0     | Anywhere |     0     |
| 'a+' |    No     | Anywhere |   End    | End only |    End    |
|------|-----------|----------|----------|----------|-----------|

Read/Write Modes for \File To Be Created

|------|----------|----------|----------|-----------|
| R/W  |          | Initial  |          | Initial   |
| Mode |  Read    | Read Pos |  Write   | Write Pos |
|------|----------|----------|----------|-----------|
| 'w'  |   Error  |    -     | Anywhere |     0     |
| 'a'  |   Error  |    -     | End only |     0     |
| 'w+' | Anywhere |    0     | Anywhere |     0     |
| 'a+' | Anywhere |    0     | End only |    End    |
|------|----------|----------|----------|-----------|

請注意,對於不存在的檔案,不允許模式 'r''r+'(會引發例外狀況)。

在表格中

現有檔案的讀取/寫入模式
要建立的檔案的讀寫模式

請注意,對於不存在的檔案,不允許模式 'r''r+'(會引發例外狀況)。

資料模式

若要指定資料應視為文字資料或二進位資料,可以將下列任一字串附加到上述任何讀寫模式

如果兩者都沒有提供,串流預設為文字資料。

範例

File.new('t.txt', 'rt')
File.new('t.dat', 'rb')

如果指定資料模式,則不能省略讀寫模式,而且資料模式必須在檔案建立模式(如果有的話)之前

File.new('t.dat', 'b')   # Raises an exception.
File.new('t.dat', 'rxb') # Raises an exception.

檔案建立模式

可以將下列字串附加到上述任何可寫入字串模式

範例

File.new('t.tmp', 'wx')

如果指定檔案建立模式,則不能省略讀寫模式,而且檔案建立模式必須在資料模式之後

File.new('t.dat', 'x')   # Raises an exception.
File.new('t.dat', 'rxb') # Raises an exception.

整數存取模式

如果模式是整數,則它必須是下列常數中的其中一個或多個,這些常數可以使用按位元 OR 運算子 | 結合

範例

File.new('t.txt', File::RDONLY)
File.new('t.tmp', File::RDWR | File::CREAT | File::EXCL)

注意:Method IO#set_encoding 不允許將模式指定為整數。

檔案建立模式指定為整數

這些常數也可以 OR 到整數模式中

資料模式指定為整數

資料模式無法指定為整數。當串流存取模式給定為整數時,資料模式永遠是文字,不會是二進位。

請注意,儘管有常數 File::BINARY,但設定其值在整數串流模式中沒有作用;這是因為,如 File::Constants 中所述,File::BINARY 值會停用換行碼轉換,但不會變更外部編碼。

編碼

上述任何字串模式都可以指定編碼,包括僅外部編碼或外部和內部編碼,方法是附加一個或兩個編碼名稱,並以冒號分隔

f = File.new('t.dat', 'rb')
f.external_encoding # => #<Encoding:ASCII-8BIT>
f.internal_encoding # => nil
f = File.new('t.dat', 'rb:UTF-16')
f.external_encoding # => #<Encoding:UTF-16 (dummy)>
f.internal_encoding # => nil
f = File.new('t.dat', 'rb:UTF-16:UTF-16')
f.external_encoding # => #<Encoding:UTF-16 (dummy)>
f.internal_encoding # => #<Encoding:UTF-16>
f.close

陣列 Encoding.name_list 中提供了許多編碼名稱

Encoding.name_list.take(3) # => ["ASCII-8BIT", "UTF-8", "US-ASCII"]

設定外部編碼時,讀取的字串會在讀取時標記為該編碼,而寫入的字串會在寫入時轉換為該編碼。

設定外部和內部編碼時,會將讀取的字串從外部編碼轉換為內部編碼,而寫入的字串會從內部編碼轉換為外部編碼。有關轉碼輸入和輸出的更多詳細資訊,請參閱 編碼

如果外部編碼是 'BOM|UTF-8''BOM|UTF-16LE''BOM|UTF16-BE',Ruby 會檢查輸入文件中的 Unicode BOM 以協助判斷編碼。對於 UTF-16 編碼,檔案開啟模式必須是二進位。如果找到 BOM,則會將其移除,並使用 BOM 中的外部編碼。

請注意,BOM 風格編碼選項不區分大小寫,因此 'bom|utf-8' 也是有效的。

檔案權限

File 物件具有權限,它是一個八進位整數,表示底層平台中實際檔案的權限。

請注意,檔案權限與檔案串流(File 物件)的模式有很大的不同。

在 File 物件中,權限可用於此,其中方法 mode 會傳回權限,儘管其名稱是模式

f = File.new('t.txt')
f.lstat.mode.to_s(8) # => "100644"

在基於 Unix 的作業系統中,三個低階八進位數字代表所有者 (6)、群組 (4) 和全世界 (4) 的權限。每個八進位數字中的三元組位元分別代表讀取、寫入和執行權限。

因此,權限 0644 代表所有者的讀寫存取權限,以及群組和全世界的唯讀存取權限。請參閱手冊頁面 open(2)chmod(2)

對於目錄,執行位元的意義會改變:設定時,可以搜尋目錄。

權限中的高階位元可能表示檔案類型(純文字、目錄、管線、socket 等)和各種其他特殊功能。

在非 Posix 作業系統中,權限可能僅包含唯讀或讀寫,在這種情況下,其餘權限將類似於典型值。例如,在 Windows 中,預設權限為 0644;唯一可以進行的變更,是將檔案設為唯讀,這會報告為 0444

對於實際在底層平台中建立檔案的方法(與僅建立 File 物件相反),可以指定權限

File.new('t.tmp', File::CREAT, 0644)
File.new('t.tmp', File::CREAT, 0444)

也可以變更權限

f = File.new('t.tmp', File::CREAT, 0444)
f.chmod(0644)
f.chmod(0444)

檔案常數

可以在模組 File::Constants 中找到各種常數,以供在 File 和 IO 方法中使用;其名稱陣列由 File::Constants.constants 傳回。

此處內容

首先,其他地方的內容。類別 File

在此,類別 File 提供對下列事項有用的方法

建立

查詢

路徑

時間

類型

內容

設定

其他

常數

ALT_SEPARATOR

特定於平台的替代分隔符號

PATH_SEPARATOR

路徑清單分隔符號

SEPARATOR

分隔路徑中目錄的部分

Separator

分隔路徑中目錄的部分

公開類別方法

absolute_path(file_name [, dir_string] ) → abs_file_name 按一下以切換來源

將路徑名稱轉換為絕對路徑名稱。相對路徑會從程序的目前工作目錄參考,除非給定 dir_string,否則會將其用作起點。如果給定的路徑名稱以「~」開頭,則不會展開,而是視為一般目錄名稱。

File.absolute_path("~oracle/bin")       #=> "<relative_path>/~oracle/bin"
static VALUE
s_absolute_path(int c, const VALUE * v, VALUE _)
{
    return rb_file_s_absolute_path(c, v);
}
absolute_path?(file_name) → true 或 false 按一下以切換來源

如果 file_name 是絕對路徑,則傳回 true,否則傳回 false

File.absolute_path?("c:/foo")     #=> false (on Linux), true (on Windows)
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 按一下以切換來源

將命名檔案的最後存取時間傳回為 Time 物件。

file_name 可以是 IO 物件。

File.atime("testfile")   #=> Wed Apr 09 08:51:48 CDT 2003
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] ) → base_name 按一下以切換來源

傳回 file_name 中給定的檔案名稱的最後組成部分(在先移除尾隨分隔符號之後),可以使用 File::SEPARATORFile::ALT_SEPARATOR 作為分隔符號來形成,當 File::ALT_SEPARATOR 不為 nil 時。如果給定 suffix,且存在於 file_name 的結尾,則會將其移除。如果 suffix 為「.*」,則會移除任何副檔名。

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"
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(file_name) → time 按一下以切換來源

傳回命名檔案的建立時間。

file_name 可以是 IO 物件。

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

如果平台沒有建立時間,則會引發 NotImplementedError

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?(filepath) → true 或 false 按一下以切換來源

如果 filepath 指向區塊裝置,則傳回 true,否則傳回 false

File.blockdev?('/dev/sda1')       # => true
File.blockdev?(File.new('t.tmp')) # => false
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?(filepath) → true 或 false 按一下以切換來源

如果 filepath 指向字元裝置,則傳回 true,否則傳回 false

File.chardev?($stdin)     # => true
File.chardev?('t.txt')     # => 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;
}
chmod(mode_int, file_name, ... ) → 整數 按一下以切換來源

將指定檔案的權限位元變更為 mode_int 所代表的位元模式。實際效果取決於作業系統(請參閱本節開頭)。在 Unix 系統上,請參閱 chmod(2) 以取得詳細資料。傳回已處理的檔案數目。

File.chmod(0644, "testfile", "out")   #=> 2
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, ...) → 整數 按一下以切換來源

將指定檔案的所有者和群組變更為指定的數字所有者和群組 ID。只有具有超級使用者權限的程序才能變更檔案的所有者。檔案的目前所有者可以將檔案的群組變更為所有者所屬的任何群組。忽略 nil 或 -1 的所有者或群組 ID。傳回已處理的檔案數目。

File.chown(nil, 100, "testfile")
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) → 時間 按一下以切換來源

傳回指定檔案的變更時間(變更檔案目錄資訊的時間,而非檔案本身)。

file_name 可以是 IO 物件。

請注意,在 Windows (NTFS) 上,會傳回建立時間(誕生時間)。

File.ctime("testfile")   #=> Wed Apr 09 08:53:13 CDT 2003
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, ...) → 整數 按一下以切換來源
unlink(file_name, ...) → 整數

刪除指定的檔案,傳回作為引數傳遞的名稱數目。發生任何錯誤時,會引發例外狀況。由於基礎實作依賴於 unlink(2) 系統呼叫,因此引發的例外狀況類型取決於其錯誤類型(請參閱 linux.die.net/man/2/unlink),且形式為 e.g. Errno::ENOENT。

另請參閱 Dir::rmdir

static VALUE
rb_file_s_unlink(int argc, VALUE *argv, VALUE klass)
{
    return apply2files(unlink_internal, argc, argv, 0);
}
directory?(path) → true 或 false 按一下以切換來源

如果 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 物件。

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, level = 1) → dir_name 按一下以切換來源

傳回 file_name 中指定的檔名的所有組成部分,唯最後一個組成部分除外(先移除尾端的區隔符號)。當 File::ALT_SEPARATOR 不為 nil 時,可以使用 File::SEPARATORFile::ALT_SEPARATOR 作為區隔符號來形成檔名。

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

如果給定 level,則移除最後 level 個組成部分,而不仅仅只移除一個。

File.dirname("/home/gumby/work/ruby.rb", 2) #=> "/home/gumby"
File.dirname("/home/gumby/work/ruby.rb", 4) #=> "/"
static VALUE
rb_file_s_dirname(int argc, VALUE *argv, VALUE klass)
{
    int n = 1;
    if ((argc = rb_check_arity(argc, 1, 2)) > 1) {
        n = NUM2INT(argv[1]);
    }
    return rb_file_dirname_n(argv[0], n);
}
zero?(file_name) → true 或 false 按一下以切換來源

如果指定的文件存在且大小為零,則傳回 true

file_name 可以是 IO 物件。

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

    if (rb_stat(fname, &st) < 0) return Qfalse;
    return RBOOL(st.st_size == 0);
}
executable?(file_name) → true 或 false 按一下以切換來源

如果指定的文件可由這個程序的有效使用者和群組 ID 執行,則傳回 true。請參閱 eaccess(3)。

Windows 不支援與讀取權限分開的執行權限。在 Windows 上,只有以 .bat、.cmd、.com 或 .exe 結尾的文件才會被視為可執行。

請注意,即使文件不可由有效使用者/群組執行,某些作業系統層級的安全功能仍可能導致此函數傳回 true。

static VALUE
rb_file_executable_p(VALUE obj, VALUE fname)
{
    return RBOOL(rb_eaccess(fname, X_OK) >= 0);
}
executable_real?(file_name) → true 或 false 按一下以切換來源

如果指定的文件可由這個程序的實際使用者和群組 ID 執行,則傳回 true。請參閱 access(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);
}
exist?(file_name) → true 或 false 按一下以切換來源

如果指定的文件存在,則傳回 true

file_name 可以是 IO 物件。

「文件存在」表示 stat() 或 fstat() 系統呼叫成功。

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

    if (rb_stat(fname, &st) < 0) return Qfalse;
    return Qtrue;
}
expand_path(file_name [, dir_string] ) → abs_file_name 按一下以切換來源

將路徑名稱轉換為絕對路徑名稱。除非給定 dir_string,否則相對路徑會從程序的目前工作目錄參考;如果給定 dir_string,則會將其用作起始點。給定的路徑名稱可以以「~」開頭,它會擴充為程序所有者的家目錄(環境變數 HOME 必須設定正確)。「~user」會擴充為指定使用者的家目錄。

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

以下是一個使用 dir_string 的簡單範例。

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

以下是一個更複雜的範例,它也會解析父目錄。假設我們在 bin/mygem 中,並想要 lib/mygem.rb 的絕對路徑。

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

因此,它首先解析 __FILE__ 的父目錄,也就是 bin/,然後前往父目錄,也就是專案的根目錄,並附加 lib/mygem.rb

static VALUE
s_expand_path(int c, const VALUE * v, VALUE _)
{
    return rb_file_s_expand_path(c, v);
}
extname(path) → 字串 按一下以切換來源

傳回副檔名(path 中從最後一個句點開始的文件名稱部分)。

如果 path 是點檔,或以句點開頭,則開頭的句點不會被視為副檔名的開頭。

當句點是 path 中的最後一個字元時,也會傳回空字串。

在 Windows 上,尾端的句點會被截斷。

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"
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) → true 或 false 按一下以切換來源

如果指定的 file 存在且為一般檔案,則傳回 true

file 可以是 IO 物件。

如果 file 參數是符號連結,它會解析符號連結並使用連結所參考的檔案。

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));
}
fnmatch( pattern, path, [flags] ) → (true 或 false) 按一下以切換來源

如果 pathpattern 相符,則傳回 true。這個樣式不是正規表示式;而是遵循類似 shell 檔案名稱萬用字元的規則。它可能包含下列的萬用字元

*

與任何檔案相符。可以透過萬用字元中的其他值加以限制。等同於正規表示式中的 /.*/x

*

與所有一般檔案相符

c*

與所有以 c 開頭的檔案相符

*c

與所有以 c 結尾的檔案相符

*c*

與所有包含 c 的檔案相符(包括開頭或結尾)。

若要與隱藏檔案(以 . 開頭)相符,請設定 File::FNM_DOTMATCH 旗標。

**

遞迴與目錄或擴充與檔案相符。

?

與任何一個字元相符。等同於正規表示式中的 /.{1}/

[set]

set 中的任何一個字元相符。行為與 Regexp 中的字元集完全相同,包括集否定([^a-z])。

\

跳脫下一個萬用字元。

{a,b}

如果啟用 File::FNM_EXTGLOB 旗標,則與樣式 a 和樣式 b 相符。行為類似 Regexp 聯集((?:a|b))。

flagsFNM_XXX 常數的按位元 OR。相同的萬用字元樣式和旗標由 Dir::glob 使用。

範例

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

File.fnmatch('**/*.rb', 'main.rb')                  #=> false
File.fnmatch('**/*.rb', './main.rb')                #=> false
File.fnmatch('**/*.rb', '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

File.fnmatch('**/foo', 'a/b/c/foo', File::FNM_PATHNAME)     #=> true
File.fnmatch('**/foo', '/a/b/c/foo', File::FNM_PATHNAME)    #=> true
File.fnmatch('**/foo', 'c:/a/b/c/foo', File::FNM_PATHNAME)  #=> true
File.fnmatch('**/foo', 'a/.b/c/foo', File::FNM_PATHNAME)    #=> false
File.fnmatch('**/foo', 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH) #=> true
# File dir.rb, line 502
def fnmatch(pattern, path, flags = 0)
end
別名為:fnmatch?
fnmatch?( pattern, path, [flags] ) → (true 或 false)
別名為:fnmatch
ftype(file_name) → 字串 按一下以切換來源

識別命名檔案的類型;回傳字串為「file」、「directory」、「characterSpecial」、「blockSpecial」、「fifo」、「link」、「socket」或「unknown」之一。

File.ftype("testfile")            #=> "file"
File.ftype("/dev/tty")            #=> "characterSpecial"
File.ftype("/tmp/.X11-unix/X0")   #=> "socket"
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) → true 或 false 按一下以切換來源

如果命名檔案存在且呼叫程序的有效群組 ID 為檔案的所有者,則傳回 true。在 Windows 上傳回 false

file_name 可以是 IO 物件。

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) → true 或 false 按一下以切換來源

如果命名檔案相同,則傳回 true

file_1file_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_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 按一下以切換來源

傳回使用「/」連接字串所形成的新字串。

File.join("usr", "mail", "gumby")   #=> "usr/mail/gumby"
static VALUE
rb_file_s_join(VALUE klass, VALUE args)
{
    return rb_file_join(args);
}
lchmod(mode_int, file_name, ...) → 整數 按一下以切換來源

等同於 File::chmod,但不會追蹤符號連結(因此它會變更與連結關聯的權限,而非連結所參考的檔案)。通常無法使用。

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,..) → 整數 按一下以切換來源

等同於 File::chown,但不會追蹤符號連結(因此它會變更與連結關聯的所有者,而非連結所參考的檔案)。通常無法使用。傳回引數清單中的檔案數量。

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);
}
lstat(filepath) → 狀態 按一下以切換來源

類似於 File::stat,但不會追蹤最後一個符號連結;而是傳回連結本身的 File::Stat 物件。

File.symlink('t.txt', 'symlink')
File.stat('symlink').size  # => 47
File.lstat('symlink').size # => 5
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, ...) → 整數 按一下以切換來源

將每個命名檔案的存取和修改時間設定為前兩個引數。如果檔案是符號連結,此方法會對連結本身執行動作,而不是其參照對象;如需反向行為,請參閱 File.utime。傳回引數清單中檔案名稱的數量。

static VALUE
rb_file_s_lutime(int argc, VALUE *argv, VALUE _)
{
    return utime_internal_i(argc, argv, TRUE);
}
mkfifo(file_name, mode=0666) → 0 按一下以切換來源

建立具有名稱 file_name 的 FIFO 特殊檔案。mode 指定 FIFO 的權限。它會以慣常的方式由程序的 umask 修改:已建立檔案的權限為 (mode & ~umask)。

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 按一下以切換來源

傳回命名檔案的修改時間,為 Time 物件。

file_name 可以是 IO 物件。

File.mtime("testfile")   #=> Tue Apr 08 12:58:04 CDT 2003
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);
}
new(path, mode = 'r', perm = 0666, **opts) → file 按一下以切換來源

根據指定的 mode 開啟位於指定 path 的檔案;建立並傳回該檔案的新 File 物件。

新的 File 物件為緩衝模式 (或非同步模式),除非 filename 是 tty。請參閱 IO#flushIO#fsyncIO#fdatasyncIO#sync=

引數 path 必須是有效的檔案路徑

f = File.new('/etc/fstab')
f.close
f = File.new('t.txt')
f.close

選用引數 mode (預設為 'r') 必須指定有效的模式;請參閱 存取模式

f = File.new('t.tmp', 'w')
f.close
f = File.new('t.tmp', File::RDONLY)
f.close

選用引數 perm (預設為 0666) 必須指定有效的權限,請參閱 檔案權限

f = File.new('t.tmp', File::CREAT, 0644)
f.close
f = File.new('t.tmp', File::CREAT, 0444)
f.close

選用關鍵字引數 opts 指定

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;
}
open(path, mode = 'r', perm = 0666, **opts) → file 按一下以切換來源
open(path, mode = 'r', perm = 0666, **opts) {|f| ... } → object

透過 File.new 建立新的 File 物件,並使用指定的引數。

若未指定區塊,傳回 File 物件。

若指定區塊,呼叫區塊並傳回區塊的值,並傳入 File 物件。

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) → true 或 false 按一下以切換來源

如果命名檔案存在,且呼叫處理程序的有效使用者識別碼為該檔案的所有者,則傳回 true

file_name 可以是 IO 物件。

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());
}
path(path) → 字串 按一下以切換來源

傳回路徑的字串表示形式

File.path(File::NULL)           #=> "/dev/null"
File.path(Pathname.new("/tmp")) #=> "/tmp"
static VALUE
rb_file_s_path(VALUE klass, VALUE fname)
{
    return rb_get_path(fname);
}
pipe?(filepath) → true 或 false 按一下以切換來源

如果 filepath 指向管線,傳回 true,否則傳回 false

File.mkfifo('tmp/fifo')
File.pipe?('tmp/fifo') # => true
File.pipe?('t.txt')    # => false
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) → true 或 false 按一下以切換來源

如果這個處理程序的有效使用者和群組識別碼可以讀取命名檔案,則傳回 true。請參閱 eaccess(3)。

請注意,某些作業系統層級的安全功能可能會導致傳回 true,即使有效使用者/群組無法讀取檔案。

static VALUE
rb_file_readable_p(VALUE obj, VALUE fname)
{
    return RBOOL(rb_eaccess(fname, R_OK) >= 0);
}
readable_real?(file_name) → true 或 false 按一下以切換來源

如果這個處理程序的實際使用者和群組識別碼可以讀取命名檔案,則傳回 true。請參閱 access(3)。

請注意,某些作業系統層級的安全功能可能會導致傳回 true,即使實際使用者/群組無法讀取檔案。

static VALUE
rb_file_readable_real_p(VALUE obj, VALUE fname)
{
    return RBOOL(rb_access(fname, R_OK) >= 0);
}
realdirpath(pathname [, dir_string]) → real_pathname 按一下以切換來源

傳回實際檔案系統中 pathname 的實際 (絕對) 路徑名稱。實際路徑名稱不包含符號連結或無用的點。

如果指定 dir_string,則使用它作為解釋相對路徑名稱的基礎目錄,而非目前目錄。

實際路徑名稱的最後一個組成部分可能不存在。

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]) → real_pathname 按一下以切換來源

傳回實際檔案系統中 pathname 的實際 (絕對) 路徑名稱,不包含符號連結或無用的點。

如果指定 dir_string,則使用它作為解釋相對路徑名稱的基礎目錄,而非目前目錄。

呼叫此方法時,路徑名稱的所有組成部分都必須存在。

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 按一下以切換來源

將給定的檔案重新命名為新的名稱。如果無法重新命名檔案,則會引發 SystemCallError

File.rename("afile", "afile.bak")   #=> 0
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) → true 或 false 按一下以切換來源

如果命名檔案已設定 setgid 位元,則傳回 true

file_name 可以是 IO 物件。

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) → true 或 false 按一下以切換來源

如果命名檔案已設定 setuid 位元,則傳回 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
}
size(file_name) → 整數 按一下以切換來源

傳回 file_name 的大小。

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);
}
size?(file_name) → 整數或 nil 按一下以切換來源

如果 file_name 不存在或大小為零,則傳回 nil;否則傳回檔案的大小。

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);
}
socket?(filepath) → true 或 false 按一下以切換來源

如果 filepath 指向 socket,則傳回 true;否則傳回 false

require 'socket'
File.socket?(Socket.new(:INET, :STREAM)) # => true
File.socket?(File.new('t.txt'))          # => false
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) → 陣列 按一下以切換來源

將給定的字串分割成目錄和檔案元件,並在兩個元素的陣列中傳回。另請參閱 File::dirnameFile::basename

File.split("/home/gumby/.profile")   #=> ["/home/gumby", ".profile"]
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(filepath) → stat 按一下以切換來源

傳回 filepath 中檔案的 File::Stat 物件(請參閱 File::Stat

File.stat('t.txt').class # => File::Stat
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) → true 或 false 按一下以切換來源

如果命名檔案已設定 sticky 位元,則傳回 true

file_name 可以是 IO 物件。

static VALUE
rb_file_sticky_p(VALUE obj, VALUE fname)
{
#ifdef S_ISVTX
    return check3rdbyte(fname, S_ISVTX);
#else
    return Qfalse;
#endif
}
truncate(file_name, integer) → 0 按一下以切換來源

將檔案 file_name 縮短至長度最多為 integer 位元組。並非所有平台都可用。

f = File.new("out", "w")
f.write("1234567890")     #=> 10
f.close                   #=> nil
File.truncate("out", 5)   #=> 0
File.size("out")          #=> 5
static VALUE
rb_file_s_truncate(VALUE klass, VALUE path, VALUE len)
{
    struct truncate_arg ta;
    int r;

    ta.pos = NUM2OFFT(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);
}
umask() → integer 按一下以切換來源
umask(integer) → integer

傳回此程序目前的 umask 值。如果提供選用引數,將 umask 設為該值並傳回前一個值。Umask 值會從預設權限中減去,因此 umask 為 0222 會讓檔案對所有人都是唯讀的。

File.umask(0006)   #=> 18
File.umask         #=> 6
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);
}
utime(atime, mtime, file_name, ...) → integer 按一下以切換來源

將每個命名檔案的存取時間和修改時間設為前兩個引數。如果檔案是符號連結,此方法會作用於其所指涉的檔案,而不是連結本身;如需相反的行為,請參閱 File.lutime。傳回引數清單中的檔案名稱數目。

static VALUE
rb_file_s_utime(int argc, VALUE *argv, VALUE _)
{
    return utime_internal_i(argc, argv, FALSE);
}
world_readable?(file_name) → integer or nil 按一下以切換來源

如果其他人可以讀取 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_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 or nil 按一下以切換來源

如果其他人可以寫入 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_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) → true or false 按一下以切換來源

如果此程序的有效使用者和群組識別碼可以寫入指定檔案,傳回 true。請參閱 eaccess(3)。

請注意,某些作業系統層級的安全功能可能會導致此方法傳回 true,即使有效使用者/群組無法寫入檔案。

static VALUE
rb_file_writable_p(VALUE obj, VALUE fname)
{
    return RBOOL(rb_eaccess(fname, W_OK) >= 0);
}
writable_real?(file_name) → true or false 按一下以切換來源

如果此程序的實際使用者和群組識別碼可以寫入指定檔案,傳回 true。請參閱 access(3)。

請注意,某些作業系統層級的安全功能可能會導致此方法傳回 true,即使實際使用者/群組無法寫入檔案。

static VALUE
rb_file_writable_real_p(VALUE obj, VALUE fname)
{
    return RBOOL(rb_access(fname, W_OK) >= 0);
}
zero?(file_name) → true 或 false 按一下以切換來源

如果指定的文件存在且大小為零,則傳回 true

file_name 可以是 IO 物件。

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

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

公開實例方法

atime → 時間 按一下以切換來源

傳回最後存取時間(時間 物件)給 檔案,或如果尚未存取過 檔案,則傳回紀元時間。

File.new("testfile").atime   #=> Wed Dec 31 18:00:00 CST 1969
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);
}
birthtime → 時間 按一下以切換來源

傳回 檔案 的建立時間。

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

如果平台沒有建立時間,則會引發 NotImplementedError

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 按一下以切換來源

檔案 的權限位元變更為 mode_int 所代表的位元模式。實際的影響取決於平台;在 Unix 系統上,請參閱 chmod(2) 以取得詳細資料。遵循符號連結。另請參閱 File#lchmod。

f = File.new("out", "w");
f.chmod(0644)   #=> 0
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 按一下以切換來源

檔案 的擁有者和群組變更為指定的數字擁有者和群組 ID。只有具備超級使用者權限的程序才能變更檔案的擁有者。檔案的現有擁有者可以將檔案的群組變更為擁有者所屬的任何群組。會忽略 nil 或 -1 的擁有者或群組 ID。遵循符號連結。另請參閱 File#lchown。

File.new("testfile").chown(502, 1000)
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);
}
ctime → 時間 按一下以切換來源

傳回 檔案 的變更時間(亦即變更檔案目錄資訊的時間,而非檔案本身)。

請注意,在 Windows (NTFS) 上,會傳回建立時間(誕生時間)。

File.new("testfile").ctime   #=> Wed Apr 09 08:53:14 CDT 2003
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 按一下以切換來源

根據指定的 locking_constant 鎖定或解鎖檔案,這是下表中值的按位元 OR。

並非所有平台都可用。

如果指定 File::LOCK_NB 且作業會造成封鎖,則傳回 false;否則傳回 0

鎖定常數
常數 鎖定 效果
File::LOCK_EX 獨佔 一次只有一個程序可以對 self 保有獨佔鎖定。
File::LOCK_NB 非封鎖 不封鎖;可以使用按位元 OR 運算子 | 與其他 File::LOCK_SHFile::LOCK_EX 結合使用。
File::LOCK_SH 共用 多個程序可以同時對 self 保有共用鎖定。
File::LOCK_UN 解鎖 移除此程序所保有的現有鎖定。


範例

# Update a counter using an exclusive lock.
# Don't use File::WRONLY because it truncates the file.
File.open('counter', File::RDWR | File::CREAT, 0644) do |f|
  f.flock(File::LOCK_EX)
  value = f.read.to_i + 1
  f.rewind
  f.write("#{value}\n")
  f.flush
  f.truncate(f.pos)
end

# Read the counter using a shared lock.
File.open('counter', 'r') do |f|
  f.flock(File::LOCK_SH)
  f.read
end
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);
}
lstat → 狀態 按一下以切換來源

類似於 File#stat,但不會遵循最後一個符號連結;而是傳回連結本身的 File::Stat 物件

File.symlink('t.txt', 'symlink')
f = File.new('symlink')
f.stat.size  # => 47
f.lstat.size # => 11
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
}
mtime → 時間 按一下以切換來源

傳回 檔案 的修改時間。

File.new("testfile").mtime   #=> Wed Apr 09 08:53:14 CDT 2003
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);
}
size → integer 點選以切換原始碼

傳回以位元組為單位的檔案大小。

File.new("testfile").size   #=> 66
static VALUE
file_size(VALUE self)
{
    return OFFT2NUM(rb_file_size(self));
}
truncate(integer) → 0 點選以切換原始碼

檔案截斷為最多整數位元組。檔案必須開啟為寫入模式。並非所有平台都支援。

f = File.new("out", "w")
f.syswrite("1234567890")   #=> 10
f.truncate(5)              #=> 0
f.close()                  #=> nil
File.size("out")           #=> 5
static VALUE
rb_file_truncate(VALUE obj, VALUE len)
{
    rb_io_t *fptr;
    struct ftruncate_arg fa;

    fa.pos = NUM2OFFT(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);
}