module IOPositioningReadWrite::IO

Public Instance Methods

readat(offset) → string or nil click to toggle source
readat(offset, length) → string or nil
readat(offset, length, buffer) → buffer or nil

指定位置から読み込むことが出来ます。

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;
}
writeat(offset, buffer) → wrote size click to toggle source

指定位置への書き込みを行います。

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