2

私はこのコードを持っています:

a = File.open("/dev/urandom")
b = a.read(1024)
a.close

puts b

/dev/urandom device\file から最初の 1024 バイトを取得することを期待していましたが、代わりに読み取りがスライスのみを受け入れ、整数を受け入れないというエラーが表示されました。

だから私はそのようにそれをやろうとしました:

b = a.read(("a" * 1000).to_slice)

しかし、その後、出力に「1000」が返されました。

Crystal のファイルから x バイトを読み取る正しい方法は何ですか?

4

1 に答える 1

8

あなたがしたことはあまり理想的ではありませんが、実際にはうまくいきました。IO#read(Slice(UInt8))ファイルが要求したものよりも小さい場合、または他の理由でデータが利用できない場合に備えて、実際に読み取られたバイト数を返します。つまり、部分読み取りです。渡したスライスが 1000 バイトでいっぱいだったので、入ります1000b可能な限り多くの要求を満たすまでブロックするものがありIO#read_fully(Slice(UInt8))ますが、いずれにしてもそれを保証することはできません.

より良いアプローチは次のようになります。

File.open("/dev/urandom") do |io|
  buffer = Bytes.new(1000) # Bytes is an alias for Slice(UInt8)
  bytes_read = io.read(buffer)
  # We truncate the slice to what we actually got back,
  # /dev/urandom never blocks, so this isn't needed in this specific
  # case, but good practice in general
  buffer = buffer[0, bytes_read] 
  pp buffer
end

IOまた、特定のトークンまで、または制限まで、さまざまなエンコーディングで文字列を読み取るためのさまざまな便利な関数も提供します。また、多くの型がインターフェースを実装しているため、from_io構造化データを簡単に読み取ることができます。

于 2016-07-24T12:51:21.107 に答える