2016-07-24 61 views
2

我有这样的代码:水晶读取x字节从文件

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

puts b 

我预计从在/ dev/urandom的设备\文件得到的第一个1024个字节,而不是我该说,读只接受片错误而不是整数。

于是,我就那样做:

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

但后来我回到“1000”的输出。

从Crystal文件中读取x字节的正确方法是什么?

回答

8

你做了什么并不是很理想,但它确实有效。 IO#read(Slice(UInt8))返回实际读取的字节数,以防文件小于您请求的数据或由于某些其他原因导致数据不可用。换句话说,这是一个部分阅读。所以你在b中得到1000,因为你传递的片段充满了1000字节。有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接口,它允许您轻松读取结构化数据。