Read a file line by line: Difference between revisions

J
(added perl)
(J)
Line 19:
}</lang>
The File is managed by reference count, and it gets closed when it gets out of scope or it changes. The 'line' is a char[] (with newline), so if you need a string you have to idup it.
 
=={{header|J}}==
 
J currently discourages this "read just one line" approach. In addition to the arbitrary character of lines, there are issues of problem size and scope (what happens when you have a billion characters between your newline delimiters?). Usually, it's easier to just read the entire file, or memory map the file, and when files are so large that that is not practical it's probably better to put the programmer in explicit control of issues like block sizes and exception handling.
 
This implementation looks for lines separated by ascii character 10. Lines returned here do not include the line separater character. Files with no line-separating character at the end are treated as well formed -- if the last character of the file is the line separator that means that you have an empty line at the end of the file.
 
This implementation does nothing special when dealing with multi-gigabyte lines. If you encounter an excessively large line and if do not have enough physical memory, your system will experience heavy memory pressure. If you also do not have enough virtual memory to hold a line you will get an out of memory exception.
 
<lang j>cocurrent 'linereader'
 
NB. configuration parameter
blocksize=: 4000
 
NB. implementation
offset=: 0
position=: 0
buffer=: ''
lines=:''
 
create=:3 :0
name=:boxxopen y
size=:1!:4 name
blocks=:2 <@(-~/\)\~.size<.blocksize*i.1+>.size%blocksize
)
 
readblocks=:3 :0
if.0=#blocks do.return.end.
if.1<#lines do.return.end.
whilst.-.LF e.chars do.
orig=:buffer=:buffer,chars=.1!:11 name,{.blocks
blocks=:}.blocks
lines=:<;._2 buffer,LF
end.
buffer=:_1{::lines
)
 
next=:3 :0
while.(#blocks)*.2>#lines do.readblock''end.
r=.0{::lines
lines=:}.lines
r
)</lang
 
<lang j> file=: '/tmp/example.txt' conew 'linereader'
next__file''
this is line 1
next__file''
this is line 2</lang>
 
=={{header|Perl}}==
6,962

edits