<div dir="ltr"><div><div><div><div><div><div><div>Two questions:<br></div>1) Do the files always contain text content?<br></div>If no, then "get_line()" would probably be a bad idea; using file:read/2 to read N bytes is a better bet. Also, open the file in 'binary' mode.<br>
</div>2) Do you expect the files to always be small?<br></div>If yes, then file:read_file/1 is nice and easy to use: it reads the entire file up and gives you the content in form of a binary.<br></div><div>Only in rare usecases would I find it necessary to read the entire file on a line-by-line basis, as your code so far does.<br>
</div><div>Simple file serving would be both simpler and faster by keeping the file data in binary form.<br></div><div>(If there needs to be done some line-ending transformation, or if the file is a pipe or similar in which the data appears slowly, line-by-line, e.g. a log, then it's of course another matter.)<br>
</div><div><br></div>With file:read_file/1, it'd be simple:<br></div> {ok,Data} = file:read_file(Filename),<br></div> % write Data to socket<br><div><div>With file:read/2 in a read-it-all loop (close to what you've written, but in essence replaceable by read_file), you'd have something like:<br>
</div><div><br></div><div> try get_data(Device)<br></div><div> of Data -> % write Data to socket<br></div><div> after file:close(Device)<br></div><div> end.<br> ...<br> -define(BLOCK_SIZE, 4096).<br> get_data(Device) -><br>
case file:read(Device, ?BLOCK_SIZE) of<br> {ok, Data} -> [Data | get_data(Device)];<br> eof -> []<br>
end.<br> <br></div><div>(Or the tail recursive equivalent.)<br></div><div>Note the "try-of" construct, which is peculiar to Erlang, but very handy - it's like the<br></div><div> try<br></div><div>
Data = get_data(Device),<br> % write Data to socket<br></div><div> after ...<br> end.<br></div><div>you'd probably write (with other syntax, of course) in other languages, except that only exceptions in the get_data() call will be caught; the "of..." clause won't be covered by the exception handler.<br>
(This is the kind of thing you probably won't think about before you learn that such a construct exists - and from then on you'll find it lacking from the languages which don't have it...)<br></div><div><br>And finally, with file:read/2 in a transfer-a-chunk-at-a-time loop, it'd be:<br>
</div><div> try transfer_data(Device, Socket)<br><div> after file:close(Device)<br></div> end.<br> ...<br> -define(BLOCK_SIZE, 4096).<br> transfer_data(Device, Socket)) -><br> case file:read(Device, ?BLOCK_SIZE) of<br>
{ok, Data} -><br> % Write Data to Socket<br></div><div> transfer_data(Device, Socket)<br></div><div> eof -> ok<br>
end.<br><br></div><div>OK, this response is long enough by now. I hope the answer helps :-)<br></div><div>/Erik<br></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/12/16 Ari King <span dir="ltr"><<a href="mailto:ari.brandeis.king@gmail.com" target="_blank">ari.brandeis.king@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div style="font-family:arial,sans-serif;font-size:13px">I've just started with Erlang and to learn/practice I'm attempting to put together a simple TCP server that reads data from a file and writes it to a socket. So far I've put together some code to read the data (combination of ascii, binary, control characters). But since (as I understand) Erlang doesn't have a return mechanism, how do I read a line of data and return it to be written to the socket? Right now, the code just recursively collects the data.<br>
<br> -module(mock_tcp).<br> -export([start/1]).<br> <br> start([Ip, Port, Filename]) -><br> io:format("Server available at ~w on port ~w. Reading from ~w.", [Ip, Port, Filename]),<br> {ok, Device) = file:open(Filename, read),<br>
try get_data(Device)<br> after file:close(Device)<br> end.<br> <br> get_data(Device) -><br> case io:get_line(Device) of<br> {ok, Data} -> [Data | get_data(Device)];<br> eof -> []<br>
end.<br><br></div><span style="font-family:arial,sans-serif;font-size:13px">Thanks.</span><span class="HOEnZb"><font color="#888888"><br><div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div>
<div><span style="font-family:arial,sans-serif;font-size:13px">Ari</span></div>
</font></span></div>
<br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br></div>