類別 ARGF

ARGF 是專門用於處理命令列引數或透過 STDIN 傳入檔案的指令碼的串流。

傳遞給指令碼的引數會儲存在 ARGV 陣列 中,每個元素一個引數。 ARGF 假設從 ARGV 中已移除任何不是檔案名稱的引數。例如

$ ruby argf.rb --verbose file1 file2

ARGV  #=> ["--verbose", "file1", "file2"]
option = ARGV.shift #=> "--verbose"
ARGV  #=> ["file1", "file2"]

現在,您可以使用 ARGF 來處理這些命名檔案的串接。例如, ARGF.read 會傳回 file1 的內容,後接 file2 的內容。

ARGV 中的檔案讀取完畢後, ARGF 會從 陣列 中將其移除。因此,在所有檔案都讀取完畢後, ARGV 將會是空的。

您可以自行操作 ARGV 來控制 ARGF 的運作方式。如果您從 ARGV 中移除檔案, ARGF 會忽略它;如果您將檔案新增到 ARGV,則會將其視為在命令列中命名。例如

ARGV.replace ["file1"]
ARGF.readlines # Returns the contents of file1 as an Array
ARGV           #=> []
ARGV.replace ["file2", "file3"]
ARGF.read      # Returns the contents of file2 and file3

如果 ARGV 為空, ARGF 會像包含 "-" 一樣運作,這會讓 ARGF 從 STDIN 讀取,也就是傳遞給或輸入到指令碼的資料。例如

$ echo "glark" | ruby -e 'p ARGF.read'
"glark\n"

$ echo Glark > file1
$ echo "glark" | ruby -e 'p ARGF.read' -- - file1
"glark\nGlark\n"

公開實例方法

argv → ARGV 按一下以切換原始碼

傳回 ARGV 陣列,其中包含傳遞給指令碼的引數,每個元素一個引數。

例如

$ ruby argf.rb -v glark.txt

ARGF.argv   #=> ["-v", "glark.txt"]
static VALUE
argf_argv(VALUE argf)
{
    return ARGF.argv;
}
binmode → ARGF 按一下以切換來源

ARGF 置於二進位模式。一旦串流處於二進位模式,就無法重設為非二進位模式。此選項具有下列效應

  • 停用換行符號轉換。

  • Encoding 轉換已停用。

  • 內容視為 ASCII-8BIT。

static VALUE
argf_binmode_m(VALUE argf)
{
    ARGF.binmode = 1;
    next_argv();
    ARGF_FORWARD(0, 0);
    rb_io_ascii8bit_binmode(ARGF.current_file);
    return argf;
}
binmode? → true 或 false 按一下以切換來源

如果 ARGF 以二進位模式讀取,則傳回 true;否則傳回 false。若要啟用二進位模式,請使用 ARGF.binmode

例如

ARGF.binmode?  #=> false
ARGF.binmode
ARGF.binmode?  #=> true
static VALUE
argf_binmode_p(VALUE argf)
{
    return RBOOL(ARGF.binmode);
}
close → ARGF 按一下以切換來源

關閉目前檔案並跳到 ARGV 中的下一檔案。如果沒有更多檔案要開啟,則只關閉目前檔案。STDIN 仍會保持開啟。

例如

$ ruby argf.rb foo bar

ARGF.filename  #=> "foo"
ARGF.close
ARGF.filename  #=> "bar"
ARGF.close
static VALUE
argf_close_m(VALUE argf)
{
    next_argv();
    argf_close(argf);
    if (ARGF.next_p != -1) {
        ARGF.next_p = 1;
    }
    ARGF.lineno = 0;
    return argf;
}
closed? → true 或 false 按一下以切換來源

如果目前檔案已關閉,則傳回 true;否則傳回 false。使用 ARGF.close 來實際關閉目前檔案。

static VALUE
argf_closed(VALUE argf)
{
    next_argv();
    ARGF_FORWARD(0, 0);
    return rb_io_closed_p(ARGF.current_file);
}
each(sep=$/) {|line| block } → ARGF 按一下以切換來源
each(sep=$/, limit) {|line| block } → ARGF
each(...) → an_enumerator

傳回一個列舉器,對 ARGV 中每個檔案的每一行(以 sep 分隔,預設為平台的換行字元)進行反覆運算。如果提供區塊,則會將每一行依序傳遞給區塊,否則會傳回一個列舉器。選用的 limit 參數是一個 Integer,用於指定每一行的最大長度;較長的列會根據此限制進行分割。

此方法允許您將命令列上提供的檔案視為一個單一檔案,由每個命名檔案的串接組成。在第一個檔案的最後一行傳回後,會傳回第二個檔案的第一行。 ARGF.filenameARGF.lineno 方法可用於分別判斷目前行的檔案名稱和整個輸入的列號。

例如,下列程式碼會印出每個命名檔案的每一行,並加上其列號,每個檔案只顯示一次檔案名稱

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.file.lineno == 1
  puts "#{ARGF.file.lineno}: #{line}"
end

而下列程式碼只會先印出第一個檔案的名稱,然後印出所有命名檔案的內容,並計算列號。

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.lineno == 1
  puts "#{ARGF.lineno}: #{line}"
end
static VALUE
argf_each_line(int argc, VALUE *argv, VALUE argf)
{
    RETURN_ENUMERATOR(argf, argc, argv);
    FOREACH_ARGF() {
        argf_block_call_line(rb_intern("each_line"), argc, argv, argf);
    }
    return argf;
}
別名為: each_line
each_byte {|byte| block } → ARGF 按一下以切換來源
each_byte → an_enumerator

逐一反覆處理 ARGV 中每個檔案的每個位元組。位元組以 0..255 範圍內的 Integer 型態傳回。

這個方法讓您能將命令列上提供的檔案視為由每個指定檔案串接而成的單一檔案。在傳回第一個檔案的最後一個位元組後,會傳回第二個檔案的第一個位元組。可以使用 ARGF.filename 方法來判斷目前位元組的檔案名稱。

如果沒有提供區塊,則會傳回一個列舉器。

例如

ARGF.bytes.to_a  #=> [35, 32, ... 95, 10]
static VALUE
argf_each_byte(VALUE argf)
{
    RETURN_ENUMERATOR(argf, 0, 0);
    FOREACH_ARGF() {
        argf_block_call(rb_intern("each_byte"), 0, 0, argf);
    }
    return argf;
}
each_char {|char| block } → ARGF 按一下以切換來源
each_char → an_enumerator

逐一反覆處理 ARGF 中每個檔案的每個字元。

這個方法讓您能將命令列上提供的檔案視為由每個指定檔案串接而成的單一檔案。在傳回第一個檔案的最後一個字元後,會傳回第二個檔案的第一個字元。可以使用 ARGF.filename 方法來判斷目前字元出現的檔案名稱。

如果沒有提供區塊,則會傳回一個列舉器。

static VALUE
argf_each_char(VALUE argf)
{
    RETURN_ENUMERATOR(argf, 0, 0);
    FOREACH_ARGF() {
        argf_block_call(rb_intern("each_char"), 0, 0, argf);
    }
    return argf;
}
each_codepoint {|codepoint| block } → ARGF 按一下以切換來源
each_codepoint → an_enumerator

逐一反覆處理 ARGF 中每個檔案的每個碼點。

這個方法讓您能將命令列上提供的檔案視為由每個指定檔案串接而成的單一檔案。在傳回第一個檔案的最後一個碼點後,會傳回第二個檔案的第一個碼點。可以使用 ARGF.filename 方法來判斷目前碼點出現的檔案名稱。

如果沒有提供區塊,則會傳回一個列舉器。

static VALUE
argf_each_codepoint(VALUE argf)
{
    RETURN_ENUMERATOR(argf, 0, 0);
    FOREACH_ARGF() {
        argf_block_call(rb_intern("each_codepoint"), 0, 0, argf);
    }
    return argf;
}
each_line(sep=$/) {|line| block } → ARGF
each_line(sep=$/, limit) {|line| block } → ARGF
each_line(...) → an_enumerator

傳回一個列舉器,對 ARGV 中每個檔案的每一行(以 sep 分隔,預設為平台的換行字元)進行反覆運算。如果提供區塊,則會將每一行依序傳遞給區塊,否則會傳回一個列舉器。選用的 limit 參數是一個 Integer,用於指定每一行的最大長度;較長的列會根據此限制進行分割。

此方法允許您將命令列上提供的檔案視為一個單一檔案,由每個命名檔案的串接組成。在第一個檔案的最後一行傳回後,會傳回第二個檔案的第一行。 ARGF.filenameARGF.lineno 方法可用於分別判斷目前行的檔案名稱和整個輸入的列號。

例如,下列程式碼會印出每個命名檔案的每一行,並加上其列號,每個檔案只顯示一次檔案名稱

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.file.lineno == 1
  puts "#{ARGF.file.lineno}: #{line}"
end

而下列程式碼只會先印出第一個檔案的名稱,然後印出所有命名檔案的內容,並計算列號。

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.lineno == 1
  puts "#{ARGF.lineno}: #{line}"
end
別名:each
eof → true 或 false 按一下以切換來源

如果 ARGF 中的目前檔案已達檔案結尾(亦即沒有資料可讀取),則傳回 true。串流必須開啟為讀取模式,否則會引發 IOError

$ echo "eof" | ruby argf.rb

ARGF.eof?                 #=> false
3.times { ARGF.readchar }
ARGF.eof?                 #=> false
ARGF.readchar             #=> "\n"
ARGF.eof?                 #=> true
static VALUE
argf_eof(VALUE argf)
{
    next_argv();
    if (RTEST(ARGF.current_file)) {
        if (ARGF.init_p == 0) return Qtrue;
        next_argv();
        ARGF_FORWARD(0, 0);
        if (rb_io_eof(ARGF.current_file)) {
            return Qtrue;
        }
    }
    return Qfalse;
}
別名:eof?
eof? → true 或 false

如果 ARGF 中的目前檔案已達檔案結尾(亦即沒有資料可讀取),則傳回 true。串流必須開啟為讀取模式,否則會引發 IOError

$ echo "eof" | ruby argf.rb

ARGF.eof?                 #=> false
3.times { ARGF.readchar }
ARGF.eof?                 #=> false
ARGF.readchar             #=> "\n"
ARGF.eof?                 #=> true
別名:eof
external_encoding → 編碼 按一下以切換來源

Encoding 物件傳回從 ARGF 讀取的檔案的外部編碼。外部編碼是儲存在檔案中的文字編碼。與 ARGF.internal_encoding 形成對比,後者是在 Ruby 中表示此文字所使用的編碼。

若要設定外部編碼,請使用 ARGF.set_encoding

例如

ARGF.external_encoding  #=>  #<Encoding:UTF-8>
static VALUE
argf_external_encoding(VALUE argf)
{
    return argf_encoding(argf, rb_io_external_encoding);
}
file → IO 或 File 物件 按一下以切換來源

傳回目前的檔案作為 IOFile 物件。當目前的檔案為 STDIN 時,會傳回 $stdin

例如

$ echo "foo" > foo
$ echo "bar" > bar

$ ruby argf.rb foo bar

ARGF.file      #=> #<File:foo>
ARGF.read(5)   #=> "foo\nb"
ARGF.file      #=> #<File:bar>
static VALUE
argf_file(VALUE argf)
{
    next_argv();
    return ARGF.current_file;
}
filename → 字串 按一下以切換來源

傳回目前的檔案名稱。當目前的檔案為 STDIN 時,會傳回 “-”。

例如

$ echo "foo" > foo
$ echo "bar" > bar
$ echo "glark" > glark

$ ruby argf.rb foo bar glark

ARGF.filename  #=> "foo"
ARGF.read(5)   #=> "foo\nb"
ARGF.filename  #=> "bar"
ARGF.skip
ARGF.filename  #=> "glark"
static VALUE
argf_filename(VALUE argf)
{
    next_argv();
    return ARGF.filename;
}
別名:path
fileno → 整數 按一下以切換來源

傳回代表目前檔案數值檔案描述符的整數。如果沒有目前的檔案,會引發 ArgumentError

ARGF.fileno    #=> 3
static VALUE
argf_fileno(VALUE argf)
{
    if (!next_argv()) {
        rb_raise(rb_eArgError, "no stream");
    }
    ARGF_FORWARD(0, 0);
    return rb_io_fileno(ARGF.current_file);
}
別名:to_i
getbyte → 整數或 nil 按一下以切換來源

ARGF 取得下一個 8 位元組 (0..255)。如果在串流的結尾呼叫,會傳回 nil

例如

$ echo "foo" > file
$ ruby argf.rb file

ARGF.getbyte #=> 102
ARGF.getbyte #=> 111
ARGF.getbyte #=> 111
ARGF.getbyte #=> 10
ARGF.getbyte #=> nil
static VALUE
argf_getbyte(VALUE argf)
{
    VALUE ch;

  retry:
    if (!next_argv()) return Qnil;
    if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
        ch = forward_current(rb_intern("getbyte"), 0, 0);
    }
    else {
        ch = rb_io_getbyte(ARGF.current_file);
    }
    if (NIL_P(ch) && ARGF.next_p != -1) {
        argf_close(argf);
        ARGF.next_p = 1;
        goto retry;
    }

    return ch;
}
getc → 字串或 nil 按一下以切換來源

ARGF 讀取下一個字元,並以 String 傳回。在串流的結尾傳回 nil

ARGF 將命令列中指定的名稱檔案視為一個檔案,其內容是串接而成的。傳回第一個檔案的最後一個字元後,會傳回第二個檔案的第一個字元,依此類推。

例如

$ echo "foo" > file
$ ruby argf.rb file

ARGF.getc  #=> "f"
ARGF.getc  #=> "o"
ARGF.getc  #=> "o"
ARGF.getc  #=> "\n"
ARGF.getc  #=> nil
ARGF.getc  #=> nil
static VALUE
argf_getc(VALUE argf)
{
    VALUE ch;

  retry:
    if (!next_argv()) return Qnil;
    if (ARGF_GENERIC_INPUT_P()) {
        ch = forward_current(rb_intern("getc"), 0, 0);
    }
    else {
        ch = rb_io_getc(ARGF.current_file);
    }
    if (NIL_P(ch) && ARGF.next_p != -1) {
        argf_close(argf);
        ARGF.next_p = 1;
        goto retry;
    }

    return ch;
}
gets(sep=$/ [, getline_args]) → 字串或 nil 按一下以切換來源
gets(limit [, getline_args]) → 字串或 nil
gets(sep, limit [, getline_args]) → 字串或 nil

傳回 ARGF 中目前檔案的下一行。

預設情況下,假設行是由 $/ 分隔;若要使用不同的字元作為分隔符號,請提供 String 作為 sep 參數。

選用的 limit 參數指定要傳回每一行的字元數。預設情況下,會傳回所有字元。

有關 getline_args 的詳細資訊,請參閱 IO.readlines

static VALUE
argf_gets(int argc, VALUE *argv, VALUE argf)
{
    VALUE line;

    line = argf_getline(argc, argv, argf);
    rb_lastline_set(line);

    return line;
}
inplace_mode → 字串 按一下以切換來源

傳回在原處編輯模式下,附加到已修改檔案備份副本名稱的檔案副檔名。可以使用 ARGF.inplace_mode= 或將 -i 開關傳遞給 Ruby 二進位檔來設定此值。

static VALUE
argf_inplace_mode_get(VALUE argf)
{
    if (!ARGF.inplace) return Qnil;
    if (NIL_P(ARGF.inplace)) return rb_str_new(0, 0);
    return rb_str_dup(ARGF.inplace);
}
inplace_mode = ext → ARGF 按一下以切換來源

將原處編輯模式的檔案名稱副檔名設定為指定的 String。每個正在編輯的檔案的備份副本都會將此值附加到其檔案名稱。

例如

$ ruby argf.rb file.txt

ARGF.inplace_mode = '.bak'
ARGF.each_line do |line|
  print line.sub("foo","bar")
end

首先,file.txt.bak 會建立為 file.txt 的備份。然後,file.txt 的每一行都會將第一次出現的「foo」替換成「bar」。

static VALUE
argf_inplace_mode_set(VALUE argf, VALUE val)
{
    if (!RTEST(val)) {
        ARGF.inplace = Qfalse;
    }
    else if (StringValueCStr(val), !RSTRING_LEN(val)) {
        ARGF.inplace = Qnil;
    }
    else {
        ARGF.inplace = rb_str_new_frozen(val);
    }
    return argf;
}
inspect
別名:to_s
internal_encoding → encoding 按一下以切換來源

傳回從 ARGF 讀取的字串的內部編碼,為 Encoding 物件。

如果 ARGF.set_encoding 已呼叫兩個編碼名稱,則會傳回第二個。否則,如果已設定 Encoding.default_external,則會傳回該值。如果沒有,如果在命令列上指定了預設外部編碼,則會使用該值。如果編碼不明,則會傳回 nil

static VALUE
argf_internal_encoding(VALUE argf)
{
    return argf_encoding(argf, rb_io_internal_encoding);
}
lineno → integer 按一下以切換來源

傳回 ARGF 的目前行號,為一個整體。這個值可以使用 ARGF.lineno= 手動設定。

例如

ARGF.lineno   #=> 0
ARGF.readline #=> "This is line 1\n"
ARGF.lineno   #=> 1
static VALUE
argf_lineno(VALUE argf)
{
    return INT2FIX(ARGF.lineno);
}
lineno = integer → integer 按一下以切換來源

ARGF 的行號設定為給定的 Integer

ARGF 會在您讀取資料時自動設定行號,因此通常不需要明確設定。若要存取目前的行號,請使用 ARGF.lineno

例如

ARGF.lineno      #=> 0
ARGF.readline    #=> "This is line 1\n"
ARGF.lineno      #=> 1
ARGF.lineno = 0  #=> 0
ARGF.lineno      #=> 0
static VALUE
argf_set_lineno(VALUE argf, VALUE val)
{
    ARGF.lineno = NUM2INT(val);
    ARGF.last_lineno = ARGF.lineno;
    return val;
}
path → String

傳回目前的檔案名稱。當目前的檔案為 STDIN 時,會傳回 “-”。

例如

$ echo "foo" > foo
$ echo "bar" > bar
$ echo "glark" > glark

$ ruby argf.rb foo bar glark

ARGF.filename  #=> "foo"
ARGF.read(5)   #=> "foo\nb"
ARGF.filename  #=> "bar"
ARGF.skip
ARGF.filename  #=> "glark"
別名:filename
pos → Integer

傳回 ARGF 中目前檔案的目前偏移量(以位元組為單位)。

ARGF.pos    #=> 0
ARGF.gets   #=> "This is line one\n"
ARGF.pos    #=> 17
別名:tell
pos = position → Integer 按一下以切換來源

ARGF 中尋找到由 position(以位元組為單位)給定的位置。

例如

ARGF.pos = 17
ARGF.gets   #=> "This is line two\n"
static VALUE
argf_set_pos(VALUE argf, VALUE offset)
{
    if (!next_argv()) {
        rb_raise(rb_eArgError, "no stream to set position");
    }
    ARGF_FORWARD(1, &offset);
    return rb_io_set_pos(ARGF.current_file, offset);
}
print(*objects) → nil 按一下以切換來源

將給定的物件寫入串流;傳回 nil。如果輸出記錄分隔符號 $OUTPUT_RECORD_SEPARATOR$\)不為 nil,則會附加該分隔符號。請參閱 行 IO

給定引數 objects 時,對於每個物件

  • 如果它不是字串,則透過其方法 to_s 轉換。

  • 寫入串流。

  • 如果不是最後一個物件,則會寫入輸出欄位分隔符號 $OUTPUT_FIELD_SEPARATOR$,),如果它不為 nil

使用預設分隔符號

f = File.open('t.tmp', 'w+')
objects = [0, 0.0, Rational(0, 1), Complex(0, 0), :zero, 'zero']
p $OUTPUT_RECORD_SEPARATOR
p $OUTPUT_FIELD_SEPARATOR
f.print(*objects)
f.rewind
p f.read
f.close

輸出

nil
nil
"00.00/10+0izerozero"

使用指定的符號

$\ = "\n"
$, = ','
f.rewind
f.print(*objects)
f.rewind
p f.read

輸出

"0,0.0,0/1,0+0i,zero,zero\n"

如果沒有給定引數,則會寫入 $_ 的內容(通常是最近的使用者輸入)

f = File.open('t.tmp', 'w+')
gets # Sets $_ to the most recent user input.
f.print
f.close
printf(format_string, *objects) → nil 按一下以切換來源

格式化並將 objects 寫入串流。

有關 format_string 的詳細資訊,請參閱 格式規格

VALUE
rb_io_printf(int argc, const VALUE *argv, VALUE out)
{
    rb_io_write(out, rb_f_sprintf(argc, argv));
    return Qnil;
}
putc(object) → object 按一下以切換來源

將一個字元寫入串流。請參閱 字元 IO

如果 object 是數字,則在必要時轉換為整數,然後寫入其代碼為最低有效位元的字元;如果 object 是字串,則寫入第一個字元

$stdout.putc "A"
$stdout.putc 65

輸出

AA
static VALUE
rb_io_putc(VALUE io, VALUE ch)
{
    VALUE str;
    if (RB_TYPE_P(ch, T_STRING)) {
        str = rb_str_substr(ch, 0, 1);
    }
    else {
        char c = NUM2CHR(ch);
        str = rb_str_new(&c, 1);
    }
    rb_io_write(io, str);
    return ch;
}
puts(*objects) → nil 按一下以切換來源

將指定的 objects 寫入串流,該串流必須開啟才能寫入;傳回 nil。在每個尚未以換行序列結尾的項目後寫入換行。如果在沒有引數的情況下呼叫,則會寫入換行。請參閱 行 IO

請注意,每個新增的換行都是字元 "\n"<//tt>,而不是輸出記錄分隔符 (<tt>$\)。

每個物件的處理方式

  • 字串:寫入字串。

  • 既不是字串也不是陣列:寫入 object.to_s

  • 陣列:寫入陣列的每個元素;陣列可以巢狀。

為了讓這些範例簡短,我們定義這個輔助方法

def show(*objects)
  # Puts objects to file.
  f = File.new('t.tmp', 'w+')
  f.puts(objects)
  # Return file content.
  f.rewind
  p f.read
  f.close
end

# Strings without newlines.
show('foo', 'bar', 'baz')     # => "foo\nbar\nbaz\n"
# Strings, some with newlines.
show("foo\n", 'bar', "baz\n") # => "foo\nbar\nbaz\n"

# Neither strings nor arrays:
show(0, 0.0, Rational(0, 1), Complex(9, 0), :zero)
# => "0\n0.0\n0/1\n9+0i\nzero\n"

# Array of strings.
show(['foo', "bar\n", 'baz']) # => "foo\nbar\nbaz\n"
# Nested arrays.
show([[[0, 1], 2, 3], 4, 5])  # => "0\n1\n2\n3\n4\n5\n"
VALUE
rb_io_puts(int argc, const VALUE *argv, VALUE out)
{
    VALUE line, args[2];

    /* if no argument given, print newline. */
    if (argc == 0) {
        rb_io_write(out, rb_default_rs);
        return Qnil;
    }
    for (int i = 0; i < argc; i++) {
        // Convert the argument to a string:
        if (RB_TYPE_P(argv[i], T_STRING)) {
            line = argv[i];
        }
        else if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
            continue;
        }
        else {
            line = rb_obj_as_string(argv[i]);
        }

        // Write the line:
        int n = 0;
        if (RSTRING_LEN(line) == 0) {
            args[n++] = rb_default_rs;
        }
        else {
            args[n++] = line;
            if (!rb_str_end_with_asciichar(line, '\n')) {
                args[n++] = rb_default_rs;
            }
        }

        rb_io_writev(out, n, args);
    }

    return Qnil;
}
read([length [, outbuf]]) → string, outbuf, or nil 按一下以切換來源

ARGF 讀取 length 位元組。這個方法會將命令列上指定的檔案串接起來,並將它們視為一個單一檔案,因此在沒有引數的情況下呼叫時,會完整傳回這個偽檔案的內容。

length 必須是非負整數或 nil

如果 length 是正整數,read 會嘗試在沒有任何轉換的情況下讀取 length 位元組(二進位模式)。如果在可以讀取任何內容之前遇到 EOF,則會傳回 nil。如果在讀取期間遇到 EOF,則會傳回少於 length 位元組。對於整數 length,產生的字串總是使用 ASCII-8BIT 編碼。

如果省略 length 或為 nil,它會讀取到 EOF,並在適用的情況下套用編碼轉換。即使在讀取任何資料前遇到 EOF,也會傳回字串。

如果 length 為零,它會傳回空字串 ("")。

如果存在選用的 outbuf 參數,它必須參考 String,它會接收資料。即使 outbuf 在一開始並非為空,在方法呼叫後,它只會包含接收的資料。

例如

$ echo "small" > small.txt
$ echo "large" > large.txt
$ ./glark.rb small.txt large.txt

ARGF.read      #=> "small\nlarge"
ARGF.read(200) #=> "small\nlarge"
ARGF.read(2)   #=> "sm"
ARGF.read(0)   #=> ""

請注意,這個方法的行為類似於 C 中的 fread() 函式。這表示它會重新嘗試呼叫 read(2) 系統呼叫,以讀取指定長度的資料。如果您需要類似於單一 read(2) 系統呼叫的行為,請考慮 ARGF#readpartialARGF#read_nonblock

static VALUE
argf_read(int argc, VALUE *argv, VALUE argf)
{
    VALUE tmp, str, length;
    long len = 0;

    rb_scan_args(argc, argv, "02", &length, &str);
    if (!NIL_P(length)) {
        len = NUM2LONG(argv[0]);
    }
    if (!NIL_P(str)) {
        StringValue(str);
        rb_str_resize(str,0);
        argv[1] = Qnil;
    }

  retry:
    if (!next_argv()) {
        return str;
    }
    if (ARGF_GENERIC_INPUT_P()) {
        tmp = argf_forward(argc, argv, argf);
    }
    else {
        tmp = io_read(argc, argv, ARGF.current_file);
    }
    if (NIL_P(str)) str = tmp;
    else if (!NIL_P(tmp)) rb_str_append(str, tmp);
    if (NIL_P(tmp) || NIL_P(length)) {
        if (ARGF.next_p != -1) {
            argf_close(argf);
            ARGF.next_p = 1;
            goto retry;
        }
    }
    else if (argc >= 1) {
        long slen = RSTRING_LEN(str);
        if (slen < len) {
            argv[0] = LONG2NUM(len - slen);
            goto retry;
        }
    }
    return str;
}
read_nonblock(maxlen[, options]) → string 按一下以切換來源
read_nonblock(maxlen, outbuf[, options]) → outbuf

ARGF 串流以非封鎖模式讀取最多 maxlen 位元組。

static VALUE
argf_read_nonblock(int argc, VALUE *argv, VALUE argf)
{
    VALUE opts;

    rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);

    if (!NIL_P(opts))
        argc--;

    return argf_getpartial(argc, argv, argf, opts, 1);
}
readbyte → Integer 按一下以切換來源

ARGF 讀取下一個 8 位元組,並將其傳回為 Integer。在讀取最後一個檔案的最後一個位元組後,會引發 EOFError

例如

$ echo "foo" > file
$ ruby argf.rb file

ARGF.readbyte  #=> 102
ARGF.readbyte  #=> 111
ARGF.readbyte  #=> 111
ARGF.readbyte  #=> 10
ARGF.readbyte  #=> end of file reached (EOFError)
static VALUE
argf_readbyte(VALUE argf)
{
    VALUE c;

    NEXT_ARGF_FORWARD(0, 0);
    c = argf_getbyte(argf);
    if (NIL_P(c)) {
        rb_eof_error();
    }
    return c;
}
readchar → String 或 nil 按一下以切換來源

ARGF 讀取下一個字元,並將其傳回為 String。在讀取最後一個檔案的最後一個字元後,會引發 EOFError

例如

$ echo "foo" > file
$ ruby argf.rb file

ARGF.readchar  #=> "f"
ARGF.readchar  #=> "o"
ARGF.readchar  #=> "o"
ARGF.readchar  #=> "\n"
ARGF.readchar  #=> end of file reached (EOFError)
static VALUE
argf_readchar(VALUE argf)
{
    VALUE ch;

  retry:
    if (!next_argv()) rb_eof_error();
    if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
        ch = forward_current(rb_intern("getc"), 0, 0);
    }
    else {
        ch = rb_io_getc(ARGF.current_file);
    }
    if (NIL_P(ch) && ARGF.next_p != -1) {
        argf_close(argf);
        ARGF.next_p = 1;
        goto retry;
    }

    return ch;
}
readline(sep=$/) → string 按一下以切換來源
readline(limit) → string
readline(sep, limit) → string

傳回 ARGF 中目前檔案的下一行。

預設情況下,假設行是由 $/ 分隔;若要使用不同的字元作為分隔符號,請提供 String 作為 sep 參數。

選用的 limit 參數指定要傳回每一行的字元數。預設情況下,會傳回所有字元。

在檔案結尾會引發 EOFError

static VALUE
argf_readline(int argc, VALUE *argv, VALUE argf)
{
    VALUE line;

    if (!next_argv()) rb_eof_error();
    ARGF_FORWARD(argc, argv);
    line = argf_gets(argc, argv, argf);
    if (NIL_P(line)) {
        rb_eof_error();
    }

    return line;
}
readlines(sep = $/, chomp: false) → array 按一下以切換來源
readlines(limit, chomp: false) → array
readlines(sep, limit, chomp: false) → array

讀取 ARGF 中的每個檔案,傳回包含檔案中行的 Array。假設各行以 sep 分隔。

lines = ARGF.readlines
lines[0]                #=> "This is line one\n"

請參閱 IO.readlines 以取得所有選項的完整說明。

static VALUE
argf_readlines(int argc, VALUE *argv, VALUE argf)
{
    long lineno = ARGF.lineno;
    VALUE lines, ary;

    ary = rb_ary_new();
    while (next_argv()) {
        if (ARGF_GENERIC_INPUT_P()) {
            lines = forward_current(rb_intern("readlines"), argc, argv);
        }
        else {
            lines = rb_io_readlines(argc, argv, ARGF.current_file);
            argf_close(argf);
        }
        ARGF.next_p = 1;
        rb_ary_concat(ary, lines);
        ARGF.lineno = lineno + RARRAY_LEN(ary);
        ARGF.last_lineno = ARGF.lineno;
    }
    ARGF.init_p = 0;
    return ary;
}
別名為:to_a
readpartial(maxlen) → 字串 按一下以切換來源
readpartial(maxlen, outbuf) → outbuf

ARGF 串流讀取最多 maxlen 位元組。

如果存在選用的 outbuf 參數,它必須參考 String,它會接收資料。即使 outbuf 在一開始並非為空,在方法呼叫後,它只會包含接收的資料。

ARGF 串流結束時,會引發 EOFError。由於 ARGF 串流是多個檔案的串接,因此內部會為每個檔案發生 EOF。ARGF.readpartial 會傳回空字串表示 EOF,但最後一個 EOF 除外,最後一個 EOF 會引發 EOFError

static VALUE
argf_readpartial(int argc, VALUE *argv, VALUE argf)
{
    return argf_getpartial(argc, argv, argf, Qnil, 0);
}
rewind → 0 按一下以切換來源

將目前檔案定位到輸入的開頭,將 ARGF.lineno 重設為零。

ARGF.readline   #=> "This is line one\n"
ARGF.rewind     #=> 0
ARGF.lineno     #=> 0
ARGF.readline   #=> "This is line one\n"
static VALUE
argf_rewind(VALUE argf)
{
    VALUE ret;
    int old_lineno;

    if (!next_argv()) {
        rb_raise(rb_eArgError, "no stream to rewind");
    }
    ARGF_FORWARD(0, 0);
    old_lineno = RFILE(ARGF.current_file)->fptr->lineno;
    ret = rb_io_rewind(ARGF.current_file);
    if (!global_argf_p(argf)) {
        ARGF.last_lineno = ARGF.lineno -= old_lineno;
    }
    return ret;
}
seek(amount, whence=IO::SEEK_SET) → 0 按一下以切換來源

根據 whence 的值,在 ARGF 串流中搜尋偏移量 amountInteger)。有關更多詳細資訊,請參閱 IO#seek

static VALUE
argf_seek_m(int argc, VALUE *argv, VALUE argf)
{
    if (!next_argv()) {
        rb_raise(rb_eArgError, "no stream to seek");
    }
    ARGF_FORWARD(argc, argv);
    return rb_io_seek_m(argc, argv, ARGF.current_file);
}
set_encoding(ext_enc) → ARGF 按一下以切換來源
set_encoding("ext_enc:int_enc") → ARGF
set_encoding(ext_enc, int_enc) → ARGF
set_encoding("ext_enc:int_enc", opt) → ARGF
set_encoding(ext_enc, int_enc, opt) → ARGF

如果指定單一引數,從 ARGF 讀取的字串會標記為指定的編碼。

如果提供兩個由冒號分隔的編碼名稱,例如「ascii:utf-8」,讀取的字串會從第一個編碼(外部編碼)轉換為第二個編碼(內部編碼),然後標記為第二個編碼。

如果指定兩個引數,它們必須是編碼物件或編碼名稱。同樣地,第一個指定外部編碼;第二個指定內部編碼。

如果指定外部編碼和內部編碼,可以使用選用 Hash 引數來調整轉換程序。此雜湊的結構在 String#encode 文件中說明。

例如

ARGF.set_encoding('ascii')         # Tag the input as US-ASCII text
ARGF.set_encoding(Encoding::UTF_8) # Tag the input as UTF-8 text
ARGF.set_encoding('utf-8','ascii') # Transcode the input from US-ASCII
                                   # to UTF-8.
static VALUE
argf_set_encoding(int argc, VALUE *argv, VALUE argf)
{
    rb_io_t *fptr;

    if (!next_argv()) {
        rb_raise(rb_eArgError, "no stream to set encoding");
    }
    rb_io_set_encoding(argc, argv, ARGF.current_file);
    GetOpenFile(ARGF.current_file, fptr);
    ARGF.encs = fptr->encs;
    return argf;
}
skip → ARGF 按一下以切換來源

將目前檔案設定為 ARGV 中的下一個檔案。如果沒有更多檔案,則不會產生任何作用。

例如

$ ruby argf.rb foo bar
ARGF.filename  #=> "foo"
ARGF.skip
ARGF.filename  #=> "bar"
static VALUE
argf_skip(VALUE argf)
{
    if (ARGF.init_p && ARGF.next_p == 0) {
        argf_close(argf);
        ARGF.next_p = 1;
    }
    return argf;
}
tell → 整數 按一下以切換來源

傳回 ARGF 中目前檔案的目前偏移量(以位元組為單位)。

ARGF.pos    #=> 0
ARGF.gets   #=> "This is line one\n"
ARGF.pos    #=> 17
static VALUE
argf_tell(VALUE argf)
{
    if (!next_argv()) {
        rb_raise(rb_eArgError, "no stream to tell");
    }
    ARGF_FORWARD(0, 0);
    return rb_io_tell(ARGF.current_file);
}
別名為:pos
to_a(sep = $/, chomp: false) → 陣列
to_a(limit, chomp: false) → 陣列
to_a(sep, limit, chomp: false) → 陣列

讀取 ARGF 中的每個檔案,傳回包含檔案中行的 Array。假設各行以 sep 分隔。

lines = ARGF.readlines
lines[0]                #=> "This is line one\n"

請參閱 IO.readlines 以取得所有選項的完整說明。

別名為: readlines
to_i → 整數

傳回代表目前檔案數值檔案描述符的整數。如果沒有目前的檔案,會引發 ArgumentError

ARGF.fileno    #=> 3
別名為: fileno
to_io → IO 按一下以切換來源

傳回表示目前檔案的 IO 物件。這會是 File 物件,除非目前的檔案是串流,例如 STDIN。

例如

ARGF.to_io    #=> #<File:glark.txt>
ARGF.to_io    #=> #<IO:<STDIN>>
static VALUE
argf_to_io(VALUE argf)
{
    next_argv();
    ARGF_FORWARD(0, 0);
    return ARGF.current_file;
}
to_s → 字串 按一下以切換來源

傳回「ARGF」。

static VALUE
argf_to_s(VALUE argf)
{
    return rb_str_new2("ARGF");
}
別名為: inspect
to_write_io → io 按一下以切換來源

如果已啟用就地模式,傳回繫結到 ARGFIO 實例以進行寫入。

static VALUE
argf_write_io(VALUE argf)
{
    if (!RTEST(ARGF.current_file)) {
        rb_raise(rb_eIOError, "not opened for writing");
    }
    return GetWriteIO(ARGF.current_file);
}
write(string) → 整數 按一下以切換來源

如果為就地模式,寫入 string

static VALUE
argf_write(VALUE argf, VALUE str)
{
    return rb_io_write(argf_write_io(argf), str);
}