Why is reading files different depending on STDIO or File.open?

Question

Reading the file seems to behave differently based on whether I am tearing away from :stdioor opening the file. What for? I would like to be able to read the binary from STDIN or open the file ( File.open) and use the same code to extract bytes.

In short:

  • Why is the behavior described below different from stdio and files?
  • How can I achieve my goal?

Test case

As a simple test case, I have a binary file containing three bytes:

06 8C 7D

My desired result is that reading this file from any source should give the binary code of the form:

<<6, 140, 125>>

However, it all seems to depend on whether I am reading from STDIO or opening a file.

Here is a series of test cases demonstrating behavior.

Example 1

IO.binread of stdio

IO.inspect IO.binread(:stdio, 3)
$ elixir repro.exs < repro.bin
{:error, :collect_chars}

2

IO.read of stdio

IO.inspect IO.read(:stdio, 3)
$ elixir repro.exs < repro.bin
<<6, 140, 125>>

3

IO.binread

{:ok, file} = File.open("repro.bin")
IO.inspect IO.binread(file, 3)
$ elixir repro.exs
<<6, 140, 125>>

4

IO.read (194), - , - utf8?

{:ok, file} = File.open("repro.bin")
IO.inspect IO.read(file, 3)
$ elixir repro.exs
<<6, 194, 140, 125>>

:

stdio . , , . , .

?

+4
1

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]

, , , , binread . : io.setopts , :

iex> io.setopts :standard_io, encoding: :latin1

, . , binread . : http://erlang.org/pipermail/erlang-bugs/2014-July/004498.html

:

  • read .
  • binread , , unicode ( -)

"" (194), , , /erlang bin utf8.

, stdio , , :

test_read = fn(device) ->
  IO.binread(device, 3)
end

#set stdio 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>>
+5

Source: https://habr.com/ru/post/1621659/


All Articles