StringIO 類別
關於範例¶ ↑
此頁面的範例假設已載入 StringIO
require 'stringio'
常數
- VERSION
公開類別方法
請注意,如果 string
已凍結,mode
預設為 'r'
。
傳回由 string
和 mode
組成的新的 StringIO 實例;請參閱 存取模式
strio = StringIO.new # => #<StringIO> strio.close
不再需要時,應關閉實例。
相關:StringIO.open
(接受區塊;自動關閉)。
static VALUE strio_initialize(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = check_strio(self); if (!ptr) { DATA_PTR(self) = ptr = strio_alloc(); } rb_call_super(0, 0); return strio_init(argc, argv, ptr, self); }
請注意,如果 string
已凍結,mode
預設為 'r'
。
由 string
和 mode
建立新的 StringIO 實例;請參閱 存取模式。
沒有區塊時,傳回新的實例
strio = StringIO.open # => #<StringIO>
有區塊時,呼叫區塊並傳回區塊的值;區塊結束時關閉實例。
StringIO.open {|strio| p strio } # => #<StringIO>
相關:StringIO.new
。
static VALUE strio_s_open(int argc, VALUE *argv, VALUE klass) { VALUE obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS); if (!rb_block_given_p()) return obj; return rb_ensure(rb_yield, obj, strio_finalize, obj); }
公開實例方法
將 self
中的資料模式設定為二進位模式;請參閱 資料模式。
static VALUE strio_binmode(VALUE self) { struct StringIO *ptr = StringIO(self); rb_encoding *enc = rb_ascii8bit_encoding(); ptr->enc = enc; if (WRITABLE(self)) { rb_enc_associate(ptr->string, enc); } return self; }
關閉 self
以進行讀取和寫入。
如果嘗試讀取或寫入,會引發 IOError
。
相關:StringIO#close_read
、StringIO#close_write
。
static VALUE strio_close(VALUE self) { StringIO(self); RBASIC(self)->flags &= ~STRIO_READWRITE; return Qnil; }
關閉 self
以進行讀取;關閉寫入設定保持不變。
如果嘗試讀取,會引發 IOError
。
相關:StringIO#close
、StringIO#close_write
。
static VALUE strio_close_read(VALUE self) { struct StringIO *ptr = StringIO(self); if (!(ptr->flags & FMODE_READABLE)) { rb_raise(rb_eIOError, "closing non-duplex IO for reading"); } RBASIC(self)->flags &= ~STRIO_READABLE; return Qnil; }
關閉 self
以進行寫入;關閉讀取設定保持不變。
如果嘗試寫入,會引發 IOError
。
相關:StringIO#close
、StringIO#close_read
。
static VALUE strio_close_write(VALUE self) { struct StringIO *ptr = StringIO(self); if (!(ptr->flags & FMODE_WRITABLE)) { rb_raise(rb_eIOError, "closing non-duplex IO for writing"); } RBASIC(self)->flags &= ~STRIO_WRITABLE; return Qnil; }
如果 self
已關閉以進行讀取和寫入,傳回 true
,否則傳回 false
。
static VALUE strio_closed(VALUE self) { StringIO(self); if (!CLOSED(self)) return Qfalse; return Qtrue; }
如果 self
已關閉以進行讀取,傳回 true
,否則傳回 false
。
static VALUE strio_closed_read(VALUE self) { StringIO(self); if (READABLE(self)) return Qfalse; return Qtrue; }
如果 self
已關閉寫入,傳回 true
,否則傳回 false
。
static VALUE strio_closed_write(VALUE self) { StringIO(self); if (WRITABLE(self)) return Qfalse; return Qtrue; }
如果提供區塊,會呼叫區塊並傳入串流中每個剩餘的位元組;請參閱 位元組 IO。
如果未提供區塊,會傳回列舉器。
static VALUE strio_each_byte(VALUE self) { struct StringIO *ptr; RETURN_ENUMERATOR(self, 0, 0); while ((ptr = strio_to_read(self)) != NULL) { char c = RSTRING_PTR(ptr->string)[ptr->pos++]; rb_yield(CHR2FIX(c)); } return self; }
如果提供區塊,會呼叫區塊並傳入串流中每個剩餘的字元;請參閱 字元 IO。
如果未提供區塊,會傳回列舉器。
static VALUE strio_each_char(VALUE self) { VALUE c; RETURN_ENUMERATOR(self, 0, 0); while (!NIL_P(c = strio_getc(self))) { rb_yield(c); } return self; }
如果提供區塊,會呼叫區塊並傳入串流中每個剩餘的碼點;請參閱 碼點 IO。
如果未提供區塊,會傳回列舉器。
static VALUE strio_each_codepoint(VALUE self) { struct StringIO *ptr; rb_encoding *enc; unsigned int c; int n; RETURN_ENUMERATOR(self, 0, 0); ptr = readable(self); enc = get_enc(ptr); while ((ptr = strio_to_read(self)) != NULL) { c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_END(ptr->string), &n, enc); ptr->pos += n; rb_yield(UINT2NUM(c)); } return self; }
呼叫區塊並傳入從串流讀取的每個剩餘行;如果已到檔案結尾,則不執行任何動作;傳回 self
。請參閱 行 IO。
傳回代表檔案編碼的 Encoding
物件。如果串流為寫入模式且未指定編碼,會傳回 nil
。
static VALUE strio_external_encoding(VALUE self) { struct StringIO *ptr = StringIO(self); return rb_enc_from_encoding(get_enc(ptr)); }
static VALUE strio_unimpl(int argc, VALUE *argv, VALUE self) { StringIO(self); rb_notimplement(); UNREACHABLE; }
傳回 nil
。僅與 IO
相容。
static VALUE strio_nil(VALUE self) { StringIO(self); return Qnil; }
傳回物件本身。僅為了與 IO
相容。
static VALUE strio_self(VALUE self) { StringIO(self); return self; }
傳回 0。僅為了與 IO
相容。
static VALUE strio_0(VALUE self) { StringIO(self); return INT2FIX(0); }
從串流中讀取並傳回下一個 8 位元組位元組;請參閱 位元組 IO。
static VALUE strio_getbyte(VALUE self) { struct StringIO *ptr = readable(self); int c; if (ptr->pos >= RSTRING_LEN(ptr->string)) { return Qnil; } c = RSTRING_PTR(ptr->string)[ptr->pos++]; return CHR2FIX(c); }
從串流中讀取並傳回下一個字元;請參閱 字元 IO。
static VALUE strio_getc(VALUE self) { struct StringIO *ptr = readable(self); rb_encoding *enc = get_enc(ptr); VALUE str = ptr->string; long pos = ptr->pos; int len; char *p; if (pos >= RSTRING_LEN(str)) { return Qnil; } p = RSTRING_PTR(str)+pos; len = rb_enc_mbclen(p, RSTRING_END(str), enc); ptr->pos += len; return enc_subseq(str, pos, len, enc); }
從串流中讀取並傳回一行;將傳回值指定給 $_
;請參閱 行 IO。
static VALUE strio_gets(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = readable(self); struct getline_arg arg; VALUE str; if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) { return rb_enc_str_new(0, 0, get_enc(ptr)); } str = strio_getline(&arg, ptr); rb_lastline_set(str); return str; }
如果指定轉換,則傳回內部字串的 編碼
。否則傳回 nil
。
static VALUE strio_internal_encoding(VALUE self) { return Qnil; }
傳回 false
。僅為了與 IO
相容。
static VALUE strio_false(VALUE self) { StringIO(self); return Qfalse; }
傳回 self
中的目前行號;請參閱 行號。
static VALUE strio_get_lineno(VALUE self) { return LONG2NUM(StringIO(self)->lineno); }
將 self
中的目前行號設定為指定的 new_line_number
;請參閱 行號。
static VALUE strio_set_lineno(VALUE self, VALUE lineno) { StringIO(self)->lineno = NUM2LONG(lineno); return lineno; }
傳回 nil
。僅與 IO
相容。
static VALUE strio_nil(VALUE self) { StringIO(self); return Qnil; }
傳回目前位置(以位元組為單位);請參閱 位置。
static VALUE strio_get_pos(VALUE self) { return LONG2NUM(StringIO(self)->pos); }
設定目前位置(以位元組為單位);請參閱 位置。
static VALUE strio_set_pos(VALUE self, VALUE pos) { struct StringIO *ptr = StringIO(self); long p = NUM2LONG(pos); if (p < 0) { error_inval(0); } ptr->pos = p; return pos; }
請參閱 IO#pread
。
static VALUE strio_pread(int argc, VALUE *argv, VALUE self) { VALUE rb_len, rb_offset, rb_buf; rb_scan_args(argc, argv, "21", &rb_len, &rb_offset, &rb_buf); long len = NUM2LONG(rb_len); long offset = NUM2LONG(rb_offset); if (len < 0) { rb_raise(rb_eArgError, "negative string size (or size too big): %" PRIsVALUE, rb_len); } if (len == 0) { if (NIL_P(rb_buf)) { return rb_str_new("", 0); } return rb_buf; } if (offset < 0) { rb_syserr_fail_str(EINVAL, rb_sprintf("pread: Invalid offset argument: %" PRIsVALUE, rb_offset)); } struct StringIO *ptr = readable(self); if (offset >= RSTRING_LEN(ptr->string)) { rb_eof_error(); } if (NIL_P(rb_buf)) { return strio_substr(ptr, offset, len, rb_ascii8bit_encoding()); } long rest = RSTRING_LEN(ptr->string) - offset; if (len > rest) len = rest; rb_str_resize(rb_buf, len); rb_enc_associate(rb_buf, rb_ascii8bit_encoding()); MEMCPY(RSTRING_PTR(rb_buf), RSTRING_PTR(ptr->string) + offset, char, len); return rb_buf; }
請參閱 IO#putc
。
static VALUE strio_putc(VALUE self, VALUE ch) { struct StringIO *ptr = writable(self); VALUE str; check_modifiable(ptr); 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); } strio_write(self, str); return ch; }
請參閱 IO#read
。
static VALUE strio_read(int argc, VALUE *argv, VALUE self) { struct StringIO *ptr = readable(self); VALUE str = Qnil; long len; int binary = 0; switch (argc) { case 2: str = argv[1]; if (!NIL_P(str)) { StringValue(str); rb_str_modify(str); } /* fall through */ case 1: if (!NIL_P(argv[0])) { len = NUM2LONG(argv[0]); if (len < 0) { rb_raise(rb_eArgError, "negative length %ld given", len); } if (len > 0 && ptr->pos >= RSTRING_LEN(ptr->string)) { if (!NIL_P(str)) rb_str_resize(str, 0); return Qnil; } binary = 1; break; } /* fall through */ case 0: len = RSTRING_LEN(ptr->string); if (len <= ptr->pos) { rb_encoding *enc = get_enc(ptr); if (NIL_P(str)) { str = rb_str_new(0, 0); } else { rb_str_resize(str, 0); } rb_enc_associate(str, enc); return str; } else { len -= ptr->pos; } break; default: rb_error_arity(argc, 0, 2); } if (NIL_P(str)) { rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr); str = strio_substr(ptr, ptr->pos, len, enc); } else { long rest = RSTRING_LEN(ptr->string) - ptr->pos; if (len > rest) len = rest; rb_str_resize(str, len); MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len); if (binary) rb_enc_associate(str, rb_ascii8bit_encoding()); else rb_enc_copy(str, ptr->string); } ptr->pos += RSTRING_LEN(str); return str; }
請參閱 IO#readlines
。
static VALUE strio_readlines(int argc, VALUE *argv, VALUE self) { VALUE ary, line; struct StringIO *ptr = readable(self); struct getline_arg arg; if (prepare_getline_args(ptr, &arg, argc, argv)->limit == 0) { rb_raise(rb_eArgError, "invalid limit: 0 for readlines"); } ary = rb_ary_new(); while (!NIL_P(line = strio_getline(&arg, ptr))) { rb_ary_push(ary, line); } return ary; }
使用指定的 other
(字串或 StringIO
)和 mode
重新初始化串流;請參閱 IO.new
StringIO.open('foo') do |strio| p strio.string strio.reopen('bar') p strio.string other_strio = StringIO.new('baz') strio.reopen(other_strio) p strio.string other_strio.close end
輸出
"foo" "bar" "baz"
static VALUE strio_reopen(int argc, VALUE *argv, VALUE self) { rb_io_taint_check(self); if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) { return strio_copy(self, *argv); } return strio_init(argc, argv, StringIO(self), self); }
將目前位置設定為指定的整數 offset
(以位元組為單位),相對於指定的常數 whence
;請參閱 位置。
static VALUE strio_seek(int argc, VALUE *argv, VALUE self) { VALUE whence; struct StringIO *ptr = StringIO(self); long amount, offset; rb_scan_args(argc, argv, "11", NULL, &whence); amount = NUM2LONG(argv[0]); if (CLOSED(self)) { rb_raise(rb_eIOError, "closed stream"); } switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) { case 0: offset = 0; break; case 1: offset = ptr->pos; break; case 2: offset = RSTRING_LEN(ptr->string); break; default: error_inval("invalid whence"); } if (amount > LONG_MAX - offset || amount + offset < 0) { error_inval(0); } ptr->pos = amount + offset; return INT2FIX(0); }
將 StringIO
的編碼指定為 ext_enc。如果 ext_enc 為 nil,請使用預設外部編碼。會忽略第 2 個參數 int_enc 和選用雜湊 opt 參數;它們是為了與 IO
的 API 相容。
static VALUE strio_set_encoding(int argc, VALUE *argv, VALUE self) { rb_encoding* enc; struct StringIO *ptr = StringIO(self); VALUE ext_enc, int_enc, opt; argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt); if (NIL_P(ext_enc)) { enc = rb_default_external_encoding(); } else { enc = rb_find_encoding(ext_enc); if (!enc) { rb_io_enc_t convconfig; int oflags, fmode; VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc); rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig); enc = convconfig.enc2; } } ptr->enc = enc; if (WRITABLE(self)) { rb_enc_associate(ptr->string, enc); } return self; }
static VALUE strio_set_encoding_by_bom(VALUE self) { struct StringIO *ptr = StringIO(self); if (!set_encoding_by_bom(ptr)) return Qnil; return rb_enc_from_encoding(ptr->enc); }
傳回緩衝區字串的大小。
static VALUE strio_size(VALUE self) { VALUE string = StringIO(self)->string; if (NIL_P(string)) { rb_raise(rb_eIOError, "not opened"); } return ULONG2NUM(RSTRING_LEN(string)); }
傳回底層字串
StringIO.open('foo') do |strio| p strio.string strio.string = 'bar' p strio.string end
輸出
"foo" "bar"
相關:StringIO#string=
(指定底層字串)。
static VALUE strio_get_string(VALUE self) { return StringIO(self)->string; }
將底層字串指定為 other_string
,並將位置設定為零;傳回 other_string
StringIO.open('foo') do |strio| p strio.string strio.string = 'bar' p strio.string end
輸出
"foo" "bar"
相關:StringIO#string
(傳回底層字串)。
static VALUE strio_set_string(VALUE self, VALUE string) { struct StringIO *ptr = StringIO(self); rb_io_taint_check(self); ptr->flags &= ~FMODE_READWRITE; StringValue(string); ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE; ptr->pos = 0; ptr->lineno = 0; RB_OBJ_WRITE(self, &ptr->string, string); return string; }
傳回 true
;僅為與其他串流類別相容而實作。
static VALUE strio_get_sync(VALUE self) { StringIO(self); return Qtrue; }
傳回未變更的引數。僅為與 IO
相容。
static VALUE strio_first(VALUE self, VALUE arg) { StringIO(self); return arg; }
傳回目前位置(以位元組為單位);請參閱 位置。
static VALUE strio_get_pos(VALUE self) { return LONG2NUM(StringIO(self)->pos); }
將緩衝區字串截斷為最多 integer 位元組。串流必須開啟為寫入模式。
static VALUE strio_truncate(VALUE self, VALUE len) { VALUE string = writable(self)->string; long l = NUM2LONG(len); long plen = RSTRING_LEN(string); if (l < 0) { error_inval("negative length"); } rb_str_resize(string, l); if (plen < l) { MEMZERO(RSTRING_PTR(string) + plen, char, l - plen); } return INT2FIX(0); }
將 8 位元組位元組推回(「取消位移」)到串流上;請參閱 位元組 IO。
static VALUE strio_ungetbyte(VALUE self, VALUE c) { struct StringIO *ptr = readable(self); check_modifiable(ptr); if (NIL_P(c)) return Qnil; if (RB_INTEGER_TYPE_P(c)) { /* rb_int_and() not visible from exts */ VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff)); const char cc = NUM2INT(v) & 0xFF; strio_unget_bytes(ptr, &cc, 1); } else { long cl; SafeStringValue(c); cl = RSTRING_LEN(c); if (cl > 0) { strio_unget_bytes(ptr, RSTRING_PTR(c), cl); RB_GC_GUARD(c); } } return Qnil; }
將字元或整數推回(「取消位移」)到串流上;請參閱 字元 IO。
static VALUE strio_ungetc(VALUE self, VALUE c) { struct StringIO *ptr = readable(self); rb_encoding *enc, *enc2; check_modifiable(ptr); if (NIL_P(c)) return Qnil; if (RB_INTEGER_TYPE_P(c)) { int len, cc = NUM2INT(c); char buf[16]; enc = rb_enc_get(ptr->string); len = rb_enc_codelen(cc, enc); if (len <= 0) rb_enc_uint_chr(cc, enc); rb_enc_mbcput(cc, buf, enc); return strio_unget_bytes(ptr, buf, len); } else { SafeStringValue(c); enc = rb_enc_get(ptr->string); enc2 = rb_enc_get(c); if (enc != enc2 && enc != rb_ascii8bit_encoding()) { c = rb_str_conv_enc(c, enc2, enc); } strio_unget_bytes(ptr, RSTRING_PTR(c), RSTRING_LEN(c)); RB_GC_GUARD(c); return Qnil; } }
將指定的字串附加到底層緩衝區字串。串流必須開啟為寫入模式。如果引數不是字串,它將使用 to_s
轉換為字串。傳回寫入的位元組數。請參閱 IO#write
。
static VALUE strio_write_m(int argc, VALUE *argv, VALUE self) { long len = 0; while (argc-- > 0) { /* StringIO can't exceed long limit */ len += strio_write(self, *argv++); } return LONG2NUM(len); }