このマニュアルは既にメンテナンスが終了したバージョンの Ruby を対象としています。 最新版のマニュアルへ

Ruby 3.1 リファレンスマニュアル

class IO::Buffer

[edit]

要約

メモリ領域を直接読み書きするための低レベルなバッファを表すクラスです。 Ruby 3.1 で導入されました。

String を経由せずにメモリ領域を扱えるため、コピーを避けた入出力 (zero-copy IO)を実現するために使われます。主に Fiber::Scheduler の実装のような、低レベルな入出力を扱う場面で利用します。

バッファは以下のいずれかの方法で確保されたメモリ領域を指します。

このクラスは実験的な機能です。利用すると「IO::Buffer is experimental and both the Ruby and C interface may change in the future!」という警告が出力されます。将来のバージョンで Ruby と C の双方のインターフェースが変更される可能性があります。

この警告は Warning[:experimental] = false を指定すると抑止できます。

buf = IO::Buffer.new(8)
p buf.size          # => 8

buf.set_string("Ruby")
p buf.get_string    # => "Ruby\x00\x00\x00\x00"
p buf.get_string(0, 4)  # => "Ruby"

目次

特異メソッド
インスタンスメソッド
定数

継承しているメソッド

Comparableから継承しているメソッド

特異メソッド

for(string) -> IO::BufferRuby 3.1 から[permalink][rdoc][edit]
for(string) {|buffer| ... } -> object

文字列 string のメモリ領域を参照する、コピーを伴わないバッファを作成します。

ブロックを渡さない場合は、string の内容を複製した凍結済みの文字列をバッファの元として使い、読み取り専用のバッファを返します。元の文字列とは切り離されるため、あとから元の文字列を変更してもバッファの内容は変わりません。

ブロックを渡した場合は、string 自身のメモリ領域を参照するバッファをブロックに渡し、ブロックの評価結果を返します。バッファへの書き込みは string に反映されます。ブロックの実行中、string は変更できません。 string が freeze されている場合は読み取り専用のバッファになります。

[PARAM] string:
バッファの元にする String を指定します。
例: ブロックを渡さない場合
buffer = IO::Buffer.for("test")
p buffer.get_string # => "test"
p buffer.external?  # => true
p buffer.readonly?  # => true

# 元の文字列を変更してもバッファには影響しない
str = +"test"
buffer = IO::Buffer.for(str)
str << "XY"
p str               # => "testXY"
p buffer.get_string # => "test"
例: ブロックを渡した場合
str = +"test"
IO::Buffer.for(str) do |buffer|
  p buffer.readonly? # => false
  buffer.set_string("Ruby")
end
p str # => "Ruby"

[SEE_ALSO] IO::Buffer.new, IO::Buffer.map

map(file, size = nil, offset = 0, flags = 0) -> IO::BufferRuby 3.1 から[permalink][rdoc][edit]

ファイルをメモリにマップしたバッファを作成して返します。

既定では書き込み可能かつ共有(shared)のマップになるため、file は書き込み可能な状態で開いておく必要があります。読み込み専用で開いたファイルをマップするには、flags に IO::Buffer::READONLY を指定します。 IO::Buffer::PRIVATE を指定するとコピーオンライトのマップになり、バッファへの変更はファイルにも他のプロセスにも反映されません。

[PARAM] file:
マップする File を指定します。
[PARAM] size:
マップするバイト数を指定します。省略するとファイル全体をマップします。0 を指定した場合と空のファイルを指定した場合はエラーになります。
[PARAM] offset:
マップを開始する位置をファイルの先頭からのバイト数で指定します。指定できる値はシステム依存で、多くの環境ではページサイズの倍数である必要があります。
[PARAM] flags:
IO::Buffer::READONLYIO::Buffer::PRIVATE を指定します。
例: 読み込み専用でマップする
File.write("test.txt", "hello world")

buffer = IO::Buffer.map(File.open("test.txt"), nil, 0, IO::Buffer::READONLY)
p buffer.get_string # => "hello world"
p buffer.mapped?    # => true
p buffer.readonly?  # => true
例: 書き込み可能なマップ
File.write("test.txt", "hello world")

buffer = IO::Buffer.map(File.open("test.txt", "r+"))
buffer.set_string("HELLO")
p File.read("test.txt") # => "HELLO world"

[SEE_ALSO] IO::Buffer.new, IO::Buffer.for

new(size = IO::Buffer::DEFAULT_SIZE, flags = 0) -> IO::BufferRuby 3.1 から[permalink][rdoc][edit]

size バイトの、0 で埋められた新しいバッファを作成して返します。

既定では内部(internal)バッファ、すなわち Ruby が直接確保したメモリ領域になります。ただし size が OS 依存の IO::Buffer::PAGE_SIZE 以上の場合は、仮想メモリ機構(Unix では匿名 mmap、Windows では VirtualAlloc)を用いて確保されます。flags に IO::Buffer::MAPPED を指定すると、 size によらず後者の方法で確保されます。

[PARAM] size:
確保するバッファのバイト数を整数で指定します。省略した場合は IO::Buffer::DEFAULT_SIZE になります。
[PARAM] flags:
バッファの確保方法を IO::Buffer::MAPPED などの定数で指定します。
buf = IO::Buffer.new(4)
p buf.size       # => 4
p buf.internal?  # => true
p buf.get_string # => "\x00\x00\x00\x00"

[SEE_ALSO] IO::Buffer.for, IO::Buffer.map

インスタンスメソッド

self <=> other -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファの大きさと内容を other と比較します。

まず大きさを比較し、大きさが同じ場合に内容をバイト列として比較します。 self の方が小さければ負の整数を、等しければ 0 を、大きければ正の整数を返します。

大きさが同じ場合の比較には C の memcmp を使い、その結果をそのまま返します。このため返る整数の絶対値に意味はありません。0 との大小だけを見てください。

Comparable を include しているため、<== などの比較演算子も使えます。

[PARAM] other:
比較対象のバッファを IO::Buffer で指定します。
[EXCEPTION] TypeError:
other が IO::Buffer でない場合に発生します。
buf = IO::Buffer.for("abc")

p(buf <=> IO::Buffer.for("abc")) # => 0
p(buf <=> IO::Buffer.for("ab"))  # => 1
p buf < IO::Buffer.for("abd")    # => true
例: 大きさが同じ場合は memcmp の結果がそのまま返る
p(IO::Buffer.for("abc") <=> IO::Buffer.for("abz")) # => -23
clear(value = 0, offset = 0, length = nil) -> selfRuby 3.1 から[permalink][rdoc][edit]

バッファを value で埋めます。

[PARAM] value:
埋める値を 0 から 255 の Integer で指定します。
[PARAM] offset:
埋め始める位置をバッファの先頭からのバイト数で指定します。
[PARAM] length:
埋めるバイト数を指定します。省略した場合はバッファの末尾までを埋めます。
[EXCEPTION] IO::Buffer::AccessError:
書き込みできないバッファに対して呼び出した場合に発生します。
buf = IO::Buffer.new(4)
buf.set_string("test")

buf.clear
p buf.get_string # => "\x00\x00\x00\x00"

# 位置と長さを指定して "A" (0x41) で埋める
buf.clear(0x41, 1, 2)
p buf.get_string # => "\x00AA\x00"
copy(source, offset = 0, length = nil, source_offset = 0) -> IntegerRuby 3.1 から[permalink][rdoc][edit]

別の IO::Buffer の内容を自身へコピーします。コピーしたバイト数を返します。

String の内容を書き込む場合は IO::Buffer#set_string を使用してください。

[PARAM] source:
コピー元を IO::Buffer で指定します。
[PARAM] offset:
書き込みを開始する位置をバッファの先頭からのバイト数で指定します。
[PARAM] length:
コピーするバイト数を指定します。省略した場合は source 全体をコピーします。
[PARAM] source_offset:
source のどの位置から読み出すかをバイト数で指定します。
[EXCEPTION] ArgumentError:
offset と length の合計がバッファのバイト数を超える場合に発生します。
[EXCEPTION] IO::Buffer::AccessError:
書き込みできないバッファに対して呼び出した場合に発生します。
buf = IO::Buffer.new(8)

p buf.copy(IO::Buffer.for("test"), 2) # => 4
p buf.get_string                      # => "\x00\x00test\x00\x00"

# 長さを指定して先頭 3 バイトだけコピーする
other = IO::Buffer.new(8)
p other.copy(IO::Buffer.for("abcdef"), 0, 3) # => 3
p other.get_string(0, 3)                     # => "abc"

[SEE_ALSO] IO::Buffer#set_string, IO::Buffer#slice

empty? -> boolRuby 3.1 から[permalink][rdoc][edit]

バッファの大きさが 0 の場合に true を返します。

大きさ 0 のバッファは、IO::Buffer.new に 0 を渡すか、空文字列から IO::Buffer.for で作った場合などにできます。

p IO::Buffer.new(0).empty? # => true
p IO::Buffer.new(4).empty? # => false
external? -> boolRuby 3.1 から[permalink][rdoc][edit]

バッファが外部(external)バッファである場合に true を返します。

外部バッファは、バッファ自身が確保・マップしたのではないメモリ領域を参照します。 IO::Buffer.for で作ったバッファは、文字列のメモリを外部参照します。外部バッファは大きさを変更できません。

p IO::Buffer.for("test").external? # => true
p IO::Buffer.new(4).external?      # => false

[SEE_ALSO] IO::Buffer#internal?

free -> selfRuby 3.1 から[permalink][rdoc][edit]

バッファが確保しているメモリ領域を解放します。

解放の内容はバッファの種類によって異なります。

  • 内部(internal) -- 確保したメモリを解放します。
  • 外部(external) -- 元のオブジェクトとの関連を解消します。
  • マップ(mapped) -- マッピングを解除します。

解放後は、どのメモリ領域も指さない状態になります。この状態のバッファを読み書きしようとすると IO::Buffer::AllocationError が発生します。

解放したバッファでも IO::Buffer#resize を呼べば、あらためてメモリ領域を確保できます。

buf = IO::Buffer.new(4)
buf.set_string("Ruby")

buf.free
p buf.null? # => true
p buf.size  # => 0

# resize すれば再び使える
buf.resize(4)
p buf.size  # => 4

[SEE_ALSO] IO::Buffer#transfer, IO::Buffer#null?

get_string(offset = 0, length = nil, encoding = Encoding::BINARY) -> StringRuby 3.1 から[permalink][rdoc][edit]

バッファの内容を String として取り出して返します。

[PARAM] offset:
読み出しを開始する位置をバッファの先頭からのバイト数で指定します。
[PARAM] length:
読み出すバイト数を指定します。省略した場合は offset からバッファの終端までを読み出します。
[PARAM] encoding:
返す文字列のエンコーディングを指定します。省略した場合は Encoding::BINARY になります。
[EXCEPTION] ArgumentError:
offset と length の合計がバッファのバイト数を超える場合に発生します。
buf = IO::Buffer.new(8)
buf.set_string("Ruby")

p buf.get_string        # => "Ruby\x00\x00\x00\x00"
p buf.get_string(0, 4)  # => "Ruby"
p buf.get_string(1, 3)  # => "uby"

p buf.get_string(0, 4).encoding.name                   # => "ASCII-8BIT"
p buf.get_string(0, 4, Encoding::UTF_8).encoding.name  # => "UTF-8"

buf.get_string(0, 99)   # ~> ArgumentError

[SEE_ALSO] IO::Buffer#set_string

get_value(buffer_type, offset) -> Integer | FloatRuby 3.1 から[permalink][rdoc][edit]

バッファの offset の位置から、buffer_type で指定した型の値を読み出して返します。

buffer_type には以下のシンボルを指定します。小文字で始まるものはリトルエンディアン、大文字で始まるものはビッグエンディアンです (1 バイトの :U8:S8 にバイトオーダーの区別はありません)。

整数

:U8 :S8 (1 バイト)、:u16 :U16 :s16 :S16 (2 バイト)、 :u32 :U32 :s32 :S32 (4 バイト)、:u64 :U64 :s64 :S64 (8 バイト)

浮動小数点数

:f32 :F32 (4 バイト)、:f64 :F64 (8 バイト)

小文字の u s f で始まるものが符号なし整数・符号付き整数・浮動小数点数を表し、 us の対応する大文字はビッグエンディアンを意味します。

[PARAM] buffer_type:
読み出す値の型を上記のシンボルで指定します。
[PARAM] offset:
読み出す位置をバッファの先頭からのバイト数で指定します。
[EXCEPTION] ArgumentError:
buffer_type が上記以外の場合や、読み出す範囲がバッファの外にはみ出す場合に発生します。
buf = IO::Buffer.for([1.5].pack("f"))
p buf.get_value(:f32, 0) # => 1.5

buf = IO::Buffer.for("\x01\x02")
p buf.get_value(:u16, 0) # => 513
p buf.get_value(:U16, 0) # => 258

[SEE_ALSO] IO::Buffer#set_value

hexdump -> String | nilRuby 3.1 から[permalink][rdoc][edit]

バッファの内容を 16 進ダンプ形式の文字列で返します。

各行は、バッファの先頭からの位置、16 進数で表したバイト列、印字できる文字による表現の順に並びます。この表示形式は将来変更される可能性があります。

メモリ領域を指していないバッファでは nil を返します。これは IO::Buffer#null? が真の場合です。

buf = IO::Buffer.for("Hello World")
puts buf.hexdump
# => 0x00000000  48 65 6c 6c 6f 20 57 6f 72 6c 64                Hello World
例: メモリ領域を指していないバッファ
buf = IO::Buffer.new(4)
buf.free
p buf.hexdump # => nil

[SEE_ALSO] IO::Buffer#inspect, IO::Buffer#null?

inspect -> StringRuby 3.1 から[permalink][rdoc][edit]

バッファの状態と内容を表した文字列を返します。

IO::Buffer#to_s と同じ 1 行に続けて、バッファの内容を IO::Buffer#hexdump と同じ 16 進ダンプ形式で表示します。この表示形式は将来変更される可能性があります。

内容をダンプするのは、バッファの大きさが 256 バイト以下の場合だけです。 256 バイトを超える場合、内容は表示されません。

buf = IO::Buffer.for("Hello World")
puts buf.inspect
# => #<IO::Buffer 0x0000000100e726b8+11 EXTERNAL READONLY SLICE>
#    0x00000000  48 65 6c 6c 6f 20 57 6f 72 6c 64                Hello World

[SEE_ALSO] IO::Buffer#to_s, IO::Buffer#hexdump

internal? -> boolRuby 3.1 から[permalink][rdoc][edit]

バッファが内部(internal)バッファである場合に true を返します。

内部バッファは、バッファ自身が確保したメモリ領域を参照します。文字列などの外部のメモリやファイルのマッピングとは結び付いていません。 IO::Buffer.new で作られるバッファは既定で内部バッファです。

p IO::Buffer.new(4).internal? # => true

[SEE_ALSO] IO::Buffer#external?

locked { ... } -> objectRuby 3.1 から[permalink][rdoc][edit]

ブロックを実行する間、バッファをロックします。ブロックの値を返します。

ロックされている間、そのバッファに対して IO::Buffer#resizeIO::Buffer#free、さらに IO::Buffer#locked を呼ぶと IO::Buffer::LockedError が発生します。バッファへの読み書き自体はロック中も行えます。

システムコールでバッファを使っている間に、そのバッファが移動したり解放されたりしないことを保証するための仕組みです。スレッド安全ではないため、複数のスレッドでバッファを共有する場合は別に同期の手段が必要です。

ブロックの実行中に例外が発生すると、ロックは解除されずに残ります。そのバッファは以降も大きさの変更や解放ができません。

[EXCEPTION] LocalJumpError:
ブロックを渡さなかった場合に発生します。
[EXCEPTION] IO::Buffer::LockedError:
すでにロックされているバッファに対して呼び出した場合に発生します。
buf = IO::Buffer.new(4)

p buf.locked?                # => false
p buf.locked { buf.locked? } # => true
p buf.locked?                # => false

# ブロックの値がそのまま返る
p buf.locked { "done" }      # => "done"
例: ロック中は大きさの変更や解放ができない
buf = IO::Buffer.new(4)
buf.locked { buf.resize(8) } # ~> IO::Buffer::LockedError

[SEE_ALSO] IO::Buffer#locked?, IO::Buffer::LOCKED

locked? -> boolRuby 3.1 から[permalink][rdoc][edit]

バッファがロックされている場合に true を返します。

ロックされたバッファは大きさの変更や解放ができず、さらにロックを取得することもできません。システムコールでバッファを使っている間に、そのバッファが移動しないことを保証するための仕組みです。

[SEE_ALSO] IO::Buffer#locked

mapped? -> boolRuby 3.1 から[permalink][rdoc][edit]

バッファがマップ(mapped)バッファである場合に true を返します。

マップバッファは、仮想メモリ機構でマップされたメモリ領域を参照します。 IO::Buffer.newIO::Buffer::MAPPED を指定した場合や、大きさが IO::Buffer::PAGE_SIZE 以上の場合は匿名のマップになります。 IO::Buffer.map で作った場合はファイルに紐づいたマップになります。

null? -> boolRuby 3.1 から[permalink][rdoc][edit]

バッファがどのメモリ領域も指していない場合に true を返します。

IO::Buffer#free で解放したバッファ、IO::Buffer#transfer で所有権を手放したバッファ、および最初からメモリ領域を確保していないバッファがこれにあたります。

p IO::Buffer.new(0).null? # => true

buf = IO::Buffer.new(4)
p buf.null? # => false
buf.free
p buf.null? # => true

[SEE_ALSO] IO::Buffer#free, IO::Buffer#transfer

pread(io, length, from) -> IntegerRuby 3.1 から[permalink][rdoc][edit]

io の指定した位置から読み込んだ内容をバッファに書き込みます。

IO::Buffer#read と異なり、読み込む位置を io の中で直接指定します。 io の現在の位置は変わりません。

[PARAM] io:
読み込み元の IO を指定します。
[PARAM] length:
読み込む最小のバイト数を整数で指定します。
[PARAM] from:
読み込みを開始する位置を、io の先頭からのバイト数で指定します。
[RETURN]
読み込んだバイト数を返します。読み込みに失敗した場合は errno を負にした整数を返します。例外は発生しません。
[EXCEPTION] ArgumentError:
offset と length の合計がバッファの大きさを超える場合に発生します。
File.write("test.txt", "Hello World")

buf = IO::Buffer.new(5)
File.open("test.txt") do |io|
  p buf.pread(io, 5, 6) # => 5
  p io.pos              # => 0
end
p buf.get_string        # => "World"

[SEE_ALSO] IO::Buffer#read, IO::Buffer#pwrite, pread(2)

pwrite(io, length, from) -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファの内容を io の指定した位置に書き込みます。

IO::Buffer#write と異なり、書き込む位置を io の中で直接指定します。 io の現在の位置は変わりません。

[PARAM] io:
書き込み先の IO を指定します。
[PARAM] length:
書き込む最小のバイト数を整数で指定します。
[PARAM] from:
書き込みを開始する位置を、io の先頭からのバイト数で指定します。
[RETURN]
書き込んだバイト数を返します。書き込みに失敗した場合は errno を負にした整数を返します。例外は発生しません。
[EXCEPTION] ArgumentError:
offset と length の合計がバッファの大きさを超える場合に発生します。
File.write("test.txt", "Hello World")

buf = IO::Buffer.for("RUBY!")
File.open("test.txt", "r+") do |io|
  p buf.pwrite(io, 5, 6) # => 5
end
p File.read("test.txt")  # => "Hello RUBY!"

[SEE_ALSO] IO::Buffer#write, IO::Buffer#pread, pwrite(2)

read(io, length) -> IntegerRuby 3.1 から[permalink][rdoc][edit]

io から読み込んだ内容をバッファに書き込みます。

読み込むのは、少なくとも length バイトです。バッファに空きがあれば、それより多く読み込むことがあります。

読み込みは io の現在の位置から行われ、io の位置は読み込んだ分だけ進みます。

[PARAM] io:
読み込み元の IO を指定します。
[PARAM] length:
読み込む最小のバイト数を整数で指定します。
[RETURN]
読み込んだバイト数を返します。読み込みに失敗した場合は errno を負にした整数を返します。例外は発生しません。
[EXCEPTION] ArgumentError:
offset と length の合計がバッファの大きさを超える場合に発生します。
File.write("test.txt", "Hello World")

buf = IO::Buffer.new(11)
File.open("test.txt") do |io|
  p buf.read(io, 11) # => 11
end
p buf.get_string     # => "Hello World"
例: 読み込みに失敗した場合は -errno を返す
File.write("test.txt", "Hello World")

buf = IO::Buffer.new(4)
# 書き込み専用で開いたファイルからは読み込めない
File.open("test.txt", "w") do |io|
  p buf.read(io, 4)      # => -9
end
p(-Errno::EBADF::Errno)  # => -9

[SEE_ALSO] IO::Buffer#pread, IO::Buffer#write

readonly? -> boolRuby 3.1 から[permalink][rdoc][edit]

バッファが読み取り専用の場合に true を返します。

読み取り専用のバッファは、IO::Buffer#set_valueIO::Buffer#set_stringIO::Buffer#copy などで変更できません。

IO::Buffer.for にブロックを渡さずに作ったバッファは、元の文字列が freeze されているかどうかによらず、常に読み取り専用になります。内部で作った文字列の複製をバッファの元として使うためです。ブロックを渡した場合は元の文字列のメモリを直接参照するため、その文字列が freeze されている場合にだけ読み取り専用になります。読み取り専用のファイルから作ったバッファも読み取り専用です。

# ブロックを渡さない場合は、元の文字列が freeze されていなくても読み取り専用
p IO::Buffer.for("test").readonly?                  # => true

# ブロックを渡した場合は元の文字列に従う
p IO::Buffer.for("test") { |buf| buf.readonly? }    # => false
p IO::Buffer.for("test".freeze) { |buf| buf.readonly? } # => true

p IO::Buffer.new(4).readonly?                       # => false
resize(size) -> selfRuby 3.1 から[permalink][rdoc][edit]

バッファの大きさを size バイトに変更します。

変更前の内容は保持されます。変更後の大きさによっては、メモリ領域が別の場所に確保しなおされ、内容がそこへコピーされます。

IO::Buffer.for で作った外部バッファや、ロックされたバッファは大きさを変更できません。

[PARAM] size:
変更後の大きさをバイト数で指定します。
[EXCEPTION] IO::Buffer::AccessError:
大きさを変更できないバッファに対して呼び出した場合に発生します。
buf = IO::Buffer.new(4)
buf.set_string("test")

buf.resize(8)
p buf.size             # => 8
p buf.get_string(0, 4) # => "test"

IO::Buffer.for("abc").resize(8) # ~> IO::Buffer::AccessError
set_string(string, offset = 0, length = nil, source_offset = 0) -> IntegerRuby 3.1 から[permalink][rdoc][edit]

文字列 string の内容をバッファに書き込みます。書き込んだバイト数を返します。

[PARAM] string:
書き込む内容を String で指定します。
[PARAM] offset:
書き込みを開始する位置をバッファの先頭からのバイト数で指定します。
[PARAM] length:
書き込むバイト数を指定します。省略した場合は string 全体を書き込みます。
[PARAM] source_offset:
string のどの位置から読み出すかをバイト数で指定します。
[EXCEPTION] ArgumentError:
offset と length の合計がバッファのバイト数を超える場合に発生します。
[EXCEPTION] IO::Buffer::AccessError:
書き込みできないバッファに対して呼び出した場合に発生します。詳しくは IO::Buffer::AccessError を参照してください。
buf = IO::Buffer.new(8)

p buf.set_string("Ruby")   # => 4
p buf.get_string           # => "Ruby\x00\x00\x00\x00"

buf.set_string("XY", 6)
p buf.get_string           # => "Ruby\x00\x00XY"

IO::Buffer.new(2).set_string("TOOLONG") # ~> ArgumentError

[SEE_ALSO] IO::Buffer#get_string

set_value(buffer_type, offset, value) -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファの offset の位置に、buffer_type で指定した型で value を書き込みます。

指定できる型は IO::Buffer#get_value を参照してください。整数の型に Float を渡した場合は、小数点以下が切り捨てられます。

offset をそのまま返します。

[PARAM] buffer_type:
書き込む値の型をシンボルで指定します。
[PARAM] offset:
書き込む位置をバッファの先頭からのバイト数で指定します。
[PARAM] value:
書き込む値を数値で指定します。
[EXCEPTION] ArgumentError:
buffer_type が不正な場合や、書き込む範囲がバッファの外にはみ出す場合に発生します。
[EXCEPTION] IO::Buffer::AccessError:
読み取り専用のバッファに対して呼び出した場合に発生します。
buf = IO::Buffer.new(8)
buf.set_value(:U8, 1, 111)
p buf.get_string # => "\x00o\x00\x00\x00\x00\x00\x00"

# 整数の型に Float を渡すと小数点以下は切り捨てられる
buf = IO::Buffer.new(8)
buf.set_value(:U32, 0, 2.5)
p buf.get_value(:U32, 0) # => 2

[SEE_ALSO] IO::Buffer#get_value

size -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファのバイト数を返します。

p IO::Buffer.new(8).size # => 8
slice(offset, length) -> IO::BufferRuby 3.1 から[permalink][rdoc][edit]

バッファの一部を指す新しい IO::Buffer を返します。

メモリのコピーは行わず、返されるバッファは元のバッファと同じメモリ領域を参照します。そのため、一方への書き込みはもう一方からも見えます。元のバッファが文字列やファイルに由来する場合、その関連も引き継がれます。

[PARAM] offset:
参照を開始する位置をバッファの先頭からのバイト数で指定します。
[PARAM] length:
参照するバイト数を指定します。
[EXCEPTION] ArgumentError:
offset や length が負の場合、または offset と length の合計がバッファのバイト数を超える場合に発生します。
buf = IO::Buffer.new(8)
buf.set_string("Ruby")

part = buf.slice(0, 4)
p part.get_string # => "Ruby"

# 同じメモリ領域を参照しているので、変更は元のバッファにも反映される
part.set_string("Xy")
p buf.get_string  # => "Xyby\x00\x00\x00\x00"

[SEE_ALSO] IO::Buffer#copy

to_s -> StringRuby 3.1 から[permalink][rdoc][edit]

バッファの状態を短く表した文字列を返します。

メモリ領域のアドレスと大きさ、状態を表すフラグが含まれます。この表示形式は将来変更される可能性があります。

p IO::Buffer.new(4).to_s # => "#<IO::Buffer 0x0000600002d10000+4 INTERNAL>"

アドレスの部分は実行するたびに変わります。

[SEE_ALSO] IO::Buffer#inspect

transfer -> IO::BufferRuby 3.1 から[permalink][rdoc][edit]

メモリ領域の所有権を新しい IO::Buffer へ移し、その新しいバッファを返します。

所有権を手放した自身は、どのメモリ領域も指さない状態になります。この状態は IO::Buffer#null? で調べられます。

buf = IO::Buffer.new(4)
buf.set_string("Ruby")

other = buf.transfer
p other.get_string # => "Ruby"

p buf.null? # => true
p buf.size  # => 0

[SEE_ALSO] IO::Buffer#free, IO::Buffer#null?

valid? -> boolRuby 3.1 から[permalink][rdoc][edit]

バッファがアクセス可能な場合に true を返します。

別のバッファや文字列の一部を参照している(IO::Buffer#slice で作った)バッファは、参照元が解放されたり別のアドレスに再確保されたりすると、アクセスできなくなります。

write(io, length) -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファの内容を io に書き込みます。

書き込むのは、少なくとも length バイトです。バッファに続きがあれば、それより多く書き込むことがあります。

書き込みは io の現在の位置から行われ、io の位置は書き込んだ分だけ進みます。

[PARAM] io:
書き込み先の IO を指定します。
[PARAM] length:
書き込む最小のバイト数を整数で指定します。
[RETURN]
書き込んだバイト数を返します。書き込みに失敗した場合は errno を負にした整数を返します。例外は発生しません。
[EXCEPTION] ArgumentError:
offset と length の合計がバッファの大きさを超える場合に発生します。
buf = IO::Buffer.for("Ruby!")
File.open("test.txt", "w") do |io|
  p buf.write(io, 5) # => 5
end
p File.read("test.txt") # => "Ruby!"

[SEE_ALSO] IO::Buffer#pwrite, IO::Buffer#read

定数

LITTLE_ENDIAN -> IntegerRuby 3.1 から[permalink][rdoc][edit]
BIG_ENDIAN -> Integer
HOST_ENDIAN -> Integer
NETWORK_ENDIAN -> Integer

バイトオーダー(エンディアン)を表す定数です。

HOST_ENDIAN は実行中の環境のバイトオーダーで、LITTLE_ENDIAN か BIG_ENDIAN のいずれかと同じ値になります。NETWORK_ENDIAN はネットワークバイトオーダーで、 BIG_ENDIAN と同じ値です。

p IO::Buffer::NETWORK_ENDIAN == IO::Buffer::BIG_ENDIAN # => true

# リトルエンディアンの環境の場合
p IO::Buffer::HOST_ENDIAN == IO::Buffer::LITTLE_ENDIAN # => true
DEFAULT_SIZE -> IntegerRuby 3.1 から[permalink][rdoc][edit]

IO::Buffer.new で size を省略した場合に使われる既定のバイト数です。

値は環境依存です。

EXTERNAL -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファが外部(external)のメモリ領域、すなわち String など他のオブジェクトが所有するメモリ領域を指していることを表すフラグです。

INTERNAL -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファが内部(internal)のメモリ領域、すなわち Ruby が直接確保したメモリ領域を指していることを表すフラグです。

LOCKED -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファがロックされていることを表すフラグです。

ロックされている間はバッファの解放やリサイズができません。バッファは IO::Buffer#locked のブロックを実行している間ロックされます。ロックされているかどうかは IO::Buffer#locked? で調べられます。

MAPPED -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファを仮想メモリ機構(Unix では匿名 mmap、Windows では VirtualAlloc)で確保することを表すフラグです。IO::Buffer.new の flags に指定します。

PAGE_SIZE -> IntegerRuby 3.1 から[permalink][rdoc][edit]

OS のページサイズをバイト数で表した値です。

IO::Buffer.new は、size がこの値以上の場合に仮想メモリ機構を用いてバッファを確保します。

値は環境依存です。

PRIVATE -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファがコピーオンライトで確保されていることを表すフラグです。

このバッファへの変更は元のメモリ領域には反映されません。

READONLY -> IntegerRuby 3.1 から[permalink][rdoc][edit]

バッファが読み込み専用であることを表すフラグです。

このフラグが立っているバッファに書き込もうとすると IO::Buffer::AccessError が発生します。