<div dir="ltr">Hi,<div><br></div><div>I agree that it is difficult to know which functions in 'file' or 'io' to use and if the file should be opened as unicode or not. Without reading the docs in all detail, it's easy to assume that since file:open takes an encoding option, the rest of the functions in the module can handle all encodings.</div><div><br></div><div>The docs say</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">The rule of thumb is that the file module should be used for files opened for bytewise access ({encoding,latin1}) and the io module should be used when accessing files with any other encoding (e.g. {encoding,uf8}).<br></blockquote><div><br></div><div>and using io:get_line/2 works, but maybe the very first step could be to make the note above stand out more proeminently in the docs? </div><div><br></div><div>Also, a simple step that can be done right away is to let file:read_line return the same error message as firle: read: {error,{no_translation,unicode,latin1}} which describes exactly what the problem is. {error, collect_line} isn't even a documented error message.</div><div><br></div><div>best regards,</div><div>Vlad</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 29, 2015 at 9:14 AM, José Valim <span dir="ltr"><<a href="mailto:jose.valim@plataformatec.com.br" target="_blank">jose.valim@plataformatec.com.br</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Pinging this thread for feedback.<div class="gmail_extra"><span class=""><br clear="all"><div><div><div><br></div><div><br></div><div><span style="font-size:13px"><div><span style="font-family:arial,sans-serif;font-size:13px;border-collapse:collapse"><b>José Valim</b></span></div><div><span style="font-family:arial,sans-serif;font-size:13px;border-collapse:collapse"><div><span style="font-family:verdana,sans-serif;font-size:x-small"><a href="http://www.plataformatec.com.br/" style="color:rgb(42,93,176)" target="_blank">www.plataformatec.com.br</a></span></div><div><span style="font-family:verdana,sans-serif;font-size:x-small">Skype: jv.ptec</span></div><div><span style="font-family:verdana,sans-serif;font-size:x-small">Founder and Lead Developer</span></div></span></div></span></div></div></div>
<br></span><div><div class="h5"><div class="gmail_quote">On Fri, Jul 4, 2014 at 5:10 PM, José Valim <span dir="ltr"><<a href="mailto:jose.valim@plataformatec.com.br" target="_blank">jose.valim@plataformatec.com.br</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello everyone,<div><br></div><div>I have found the documentation or implementation file:read/2 to be misleading when working with unicode devices in binary mode. I will use file:read_line/1 in the examples below but the issue applies to file:read/2, file:pread/1 and etc.</div>
<div><br></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div>$ echo "héllo" > foo</div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div>$ erl</div>
<div><div>1> {ok, F} = file:open("foo", [binary, unicode]).</div><div>{ok,<0.34.0>}</div><div>2> {ok, Bin} = file:read_line(F).</div><div>{ok,<<"héllo\n">>}</div></div><div>3> <<Bin/binary, 0>>.</div>
<div><<104,233,108,108,111,10, 0>><br></div></blockquote></div><div><div><div><br></div><div>Not the result is not the one desired because I expected a binary containing <<"héllo\n"/utf8>>, or more explicitly, I expected it to contain the bytes <<195, 169>> instead of <<233>>. In other words, I got latin1 as result. With char lists, we would get "héllo\n" but the function will fail for any codepoint > 255.</div>
<div><br></div><div>Note this behaviour also happens if I use file:read_line/1 on any other IO device set to unicode (like standard_io).</div><div><br></div><div>The trouble I have with the function is that it is aimed to byte-oriented but it only really works for latin1 files. If you have a unicode file, the behaviour seems to be broken for binaries, and it only works for a limited range of codepoints when using char lists.</div>
<div><br></div><div>It is interesting to notice those functions use the old {get_line, Prompt} messages which, <a href="http://www.erlang.org/doc/apps/stdlib/io_protocol.html" target="_blank">according to the I/O protocol guide</a>, should not exist beyond R15B (section 1.3). The same section above suggests to translate {get_line, Prompt} to {get_line, latin1, Prompt} which seems to be the root cause of the issues above: those functions were never meant to work with unicode devices.</div>
<div><br></div><div>Unless I am terribly wrong, I can think of some ways to fix those functions:</div><div><br></div><div>1. Keep its dual aspect of returning bytes and/or characters but fix the bug when working with unicode. This means the {get_line, Prompt} should rather translate to {get_line, EncodingOfTheIODevice, Prompt}</div>
<div><br></div><div>2. Make them crash if the encoding of the device is not latin1. This means we translate {get_line, Prompt} to {get_line, latin1, Prompt} only if the encoding of the device is latin1.</div><div><br></div>
<div>3. Make it always work at the byte level, regardless of the encoding of the IO device. This would require assigning new meaning to the {get_line, Prompt} message, so I believe it is not going to happen (although it would be a useful feature in my opinion).</div>
<div><br></div><div>Given that the original IO messages were never meant to work with unicode, maybe 2) is the best way to go here. Both 1) and 2) would require a small amendment to the current I/O protocol advice but I would argue it is necessary to fix the current limitations/bugs when working with unicode.</div><span><font color="#888888">
<div><br></div><div><span style="font-size:13px"><div><span style="font-family:arial,sans-serif;font-size:13px;border-collapse:collapse"><b>José Valim</b></span></div><div><span style="font-family:arial,sans-serif;font-size:13px;border-collapse:collapse"><div>
<span style="font-family:verdana,sans-serif;font-size:x-small"><a href="http://www.plataformatec.com.br/" style="color:rgb(42,93,176)" target="_blank">www.plataformatec.com.br</a></span></div><div><span style="font-family:verdana,sans-serif;font-size:x-small">Skype: jv.ptec</span></div>
<div><span style="font-family:verdana,sans-serif;font-size:x-small">Founder and Lead Developer</span></div></span></div></span></div></font></span></div>
</div></div>
</blockquote></div><br></div></div></div></div>
<br>_______________________________________________<br>
erlang-bugs mailing list<br>
<a href="mailto:erlang-bugs@erlang.org">erlang-bugs@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-bugs" target="_blank">http://erlang.org/mailman/listinfo/erlang-bugs</a><br>
<br></blockquote></div><br></div>