JoséValim对elixir google小组的回答:
您的问题的答案是源的编码.STDIO默认为unicode,这意味着它不适合binread.这在binread函数中有记录,目前是Erlang错误/限制.要找出编码,请使用getopts:
iex> :io.getopts :standard_io [expand_fun: &IEx.Autocomplete.expand/1, echo: true, binary: true, encoding: :unicode]
另一方面,File处于latin状态,这意味着read将尝试转换,binread将返回原始字节.您可以尝试使用:io.setopts并查看是否获得了所需的结果:
iex> io.setopts :standard_io, encoding: :latin1
我知道情况并不理想.如果无论文件的编码如何,binread始终可以读取字节,这将是很好的.我在这里写了一篇报告:http://erlang.org/pipermail/erlang-bugs/2014-July/004498.html
总结一下:
read将始终尝试转换为设备编码
binread应该总是返回原始二进制文件,但是在unicode(这是IO设备的默认设置)方面存在一个错误
我看到的额外字节(194)的奇怪"注入"似乎是elixir/erlang试图将bin解释为utf8.
根据他的建议,直接设置stdio的编码似乎可以解决问题:
test_read = fn(device) ->
IO.binread(device, 3)
end
#set stdio's encoding to latin1
:io.setopts(:standard_io, encoding: :latin1)
# Test the read against stdio
IO.inspect test_read.(:stdio)
#grab a file descriptor
{:ok, fd} = File.open("repro.bin")
# Test the same read against a file
IO.inspect test_read.(fd)
输出:
$ elixir repro.exs < repro.bin <<6, 140, 125>> <<6, 140, 125>>