module IOPositioningReadWrite::IO
Public Instance Methods
指定位置から読み込むことが出来ます。
IO#read との違いは、IO#pos= と IO#read との間でスレッドスイッチが発生することによる、 意図したストリーム位置から read できないという問題がないことです。
- RETURN
-
正常に読み込んだ場合、データが格納された buffer、もしくは String インスタンスを返します。
ファイルサイズを越えた位置を offset に与えた場合、nil を返します。
- offset
-
読み込み位置をバイト値で指定します。
これはストリーム先端からの絶対位置となります。
負の整数を指定した場合、ファイル終端からの相対位置になります。 File#seek に SEEK_END で負の値を指定した場合と同じです。
nil を指定した場合、
seek(0, SEEK_END)
と同等となります。 - length (省略可能)
-
読み込むデータ長をバイト値で指定します。
省略もしくは nil を指定すると、ファイルの最後まで読み込みます。
- buffer (省略可能)
-
読み込み先バッファとして指定します。
省略もしくは nil を指定すると、IO#readat 内部で勝手に用意します。
buffer は変更可能 (frozen ではない String) なインスタンスである必要があります。
- EXCEPTIONS
-
いろいろ。
Errno::EXXX だったり、SEGV だったり、これらにとどまりません。
処理中は呼び出しスレッドのみが停止します (GVL を開放します)。 その間別スレッドから buffer オブジェクトの変更はできなくなります (厳密に言うと、内部バッファの伸縮を伴う操作が出来なくなるだけです)。
注意点¶ ↑
Windows においては、#readat 後に IO
位置が更新されます (IO#pos= と IO#read した後と同じ位置)。 これは Windows 上の制限となります。
static VALUE io_readat(int argc, VALUE argv[], VALUE io) { VALUE offset, length = Qnil, buffer = Qnil; struct readat_args args; rb_scan_args(argc, argv, "12", &offset, &length, &buffer); io_readat_security(io, offset, length, buffer); rb_check_type(io, RUBY_T_FILE); GetOpenFile(io, args.fptr); rb_io_check_char_readable(args.fptr); ext_getoffset(io, args.fptr->fd, offset, &args.offset); if (NIL_P(length)) { buffer = io_readat_all(&args, buffer); } else { args.nbytes = NUM2SIZET(length); if (args.nbytes > 0) { buffer = io_readat_partial(&args, buffer); } else { if (NIL_P(buffer)) { buffer = rb_str_new(0, 0); } else { rb_str_set_len(buffer, 0); } } } if (!NIL_P(buffer)) { OBJ_TAINT(buffer); } return buffer; }
指定位置への書き込みを行います。
- RETURN
-
書き込んだデータ量がバイト値で返ります。
- offset
-
書き込み位置をバイト値で指定します。これはストリーム先端からの絶対位置となります。
- buffer
-
書き込みたいデータが格納されたStringインスタンスを指定します。
- EXCEPTIONS
-
Errno::EXXX や、SEGV など。
処理中は呼び出しスレッドのみが停止します (GVL を開放します)。 また、別スレッドから buffer オブジェクトの変更はできなくなります (厳密に言うと、内部バッファの伸縮を伴う操作が出来なくなるだけです)。
static VALUE io_writeat(VALUE io, VALUE offset, VALUE buffer) { rb_secure(4); rb_check_type(io, RUBY_T_FILE); struct writeat_args args; StringValue(buffer); args.nbytes = RSTRING_LEN(buffer); GetOpenFile(io, args.fptr); rb_io_check_closed(args.fptr); ext_getoffset(io, args.fptr->fd, offset, &args.offset); rb_str_locktmp(buffer); args.buf = RSTRING_PTR(buffer); ssize_t n = (ssize_t)rb_ensure(RUBY_METHOD_FUNC(io_writeat_try), (VALUE)&args, rb_str_unlocktmp, buffer); if (n < 0) { rb_sys_fail(NIL_P(args.fptr->pathv) ? NULL : RSTRING_PTR(args.fptr->pathv)); } return SIZET2NUM(n); }