Rosetta Code is being used as source material in a research project! Preview the paper and leave comments. --Michael Mol (talk) 12:03, 23 September 2014 (UTC)

Read a file line by line

From Rosetta Code
Jump to: navigation, search
Task
Read a file line by line
You are encouraged to solve this task according to the task description, using any language you may know.

Read a file one line at a time, as opposed to reading the entire file at once.

See also

Contents

[edit] Ada

Works with: Ada 2005

line_by_line.adb:

with Ada.Text_IO;
procedure Line_By_Line is
Filename  : String := "line_by_line.adb";
File  : Ada.Text_IO.File_Type;
Line_Count : Natural := 0;
begin
Ada.Text_IO.Open (File => File,
Mode => Ada.Text_IO.In_File,
Name => Filename);
while not Ada.Text_IO.End_Of_File (File) loop
declare
Line : String := Ada.Text_IO.Get_Line (File);
begin
Line_Count := Line_Count + 1;
Ada.Text_IO.Put_Line (Natural'Image (Line_Count) & ": " & Line);
end;
end loop;
Ada.Text_IO.Close (File);
end Line_By_Line;

Output:

 1: with Ada.Text_IO;
 2: procedure Line_By_Line is
 3:    Filename   : String := "line_by_line.adb";
 4:    File       : Ada.Text_IO.File_Type;
 5:    Line_Count : Natural := 0;
 6: begin
 7:    Ada.Text_IO.Open (File => File,
 8:                      Mode => Ada.Text_IO.In_File,
 9:                      Name => Filename);
 10:    while not Ada.Text_IO.End_Of_File (File) loop
 11:       declare
 12:          Line : String := Ada.Text_IO.Get_Line (File);
 13:       begin
 14:          Line_Count := Line_Count + 1;
 15:          Ada.Text_IO.Put_Line (Natural'Image (Line_Count) & ": " & Line);
 16:       end;
 17:    end loop;
 18:    Ada.Text_IO.Close (File);
 19: end Line_By_Line;

[edit] Aime

file f;
text s;
 
f_affix(f, "src/aime.c");
 
while (f_line(f, s) != -1) {
o_text(s);
o_byte('\n');
}

[edit] ALGOL 68

Works with: ALGOL 68 version Revision 1 - no extension to language used.
Works with: ALGOL 68G version Any - tested with release algol68g-2.3.5.
File: ./Read_a_file_line_by_line.a68
#!/usr/local/bin/a68g --script #
 
FILE foobar;
INT errno = open(foobar, "Read_a_file_line_by_line.a68", stand in channel);
 
STRING line;
FORMAT line fmt = $gl$;
 
PROC mount next tape = (REF FILE file)BOOL: (
print("Please mount next tape or q to quit");
IF read char = "q" THEN done ELSE TRUE FI
);
 
on physical file end(foobar, mount next tape);
on logical file end(foobar, (REF FILE skip)BOOL: done);
 
FOR count DO
getf(foobar, (line fmt, line));
printf(($g(0)": "$, count, line fmt, line))
OD;
done: SKIP
Output:
1: #!/usr/local/bin/a68g --script #
2: 
3: FILE foobar;
4: INT errno = open(foobar, "Read_a_file_line_by_line.a68", stand in channel);
5: 
6: STRING line;
7: FORMAT line fmt = $gl$;
8: 
9: PROC mount next tape = (REF FILE file)BOOL: (
10:   print("Please mount next tape or q to quit");
11:   IF read char = "q" THEN done ELSE TRUE FI
12: );
13: 
14: on physical file end(foobar, mount next tape);
15: on logical file end(foobar, (REF FILE skip)BOOL: done);
16: 
17: FOR count DO
18:   getf(foobar, (line fmt, line));
19:   printf(($g(0)": "$, count, line fmt, line))
20: OD;
21: done: SKIP

[edit] AutoHotkey

; --> Prompt the user to select the file being read
 
FileSelectFile, File, 1, %A_ScriptDir%, Select the (text) file to read, Documents (*.txt) ; Could of course be set to support other filetypes
If Errorlevel ; If no file selected
ExitApp
 
; --> Main loop: Input (File), Output (Text)
 
Loop
{
FileReadLine, Line, %File%, %A_Index% ; Reads line N (where N is loop iteration)
if Errorlevel ; If line does not exist, break loop
break
Text .= A_Index ". " Line . "`n" ; Appends the line to the variable "Text", adding line number before & new line after
}
 
; --> Delivers the output as a text file
 
FileDelete, Output.txt ; Makes sure output is clear before writing
FileAppend, %Text%, Output.txt ; Writes the result to Output.txt
Run Output.txt ; Shows the created file

[edit] AWK

awk '{ print $0 }' filename

[edit] BASIC

[edit] Locomotive Basic

10 OPENIN"foo.txt"
20 WHILE NOT EOF
30 LINE INPUT#9,i$
40 PRINT i$
50 WEND

[edit] ZX Spectrum Basic

The tape recorder interface does not support fragmented reads, because tape recorder start and stop is not atomic, (and a leadin is required for tape input). However, the microdrive does support fragmented reads. In the following example, we read a file line by line from a file on microdrive 1.

10 REM open my file for input
20 OPEN #4;"m";1;"MYFILE": REM stream 4 is the first available for general purpose
30 INPUT #4; LINE a$: REM a$ will hold our line from the file
40 REM because we do not know how many lines are in the file, we need an error trap
50 REM to gracefully exit when the file is read. (omitted from this example)
60 REM to prevent an error at end of file, place a handler here
100 GOTO 30

[edit] Batch File

 
@echo off
for /f "tokens=* delims=" %%i in (file.txt) do echo %%i
 

[edit] BBC BASIC

This method is appropriate if the lines are terminated by a single CR or LF:

      file% = OPENIN("*.txt")
IF file%=0 ERROR 100, "File could not be opened"
WHILE NOT EOF#file%
a$ = GET$#file%
ENDWHILE
CLOSE #file%

This method is appropriate if the lines are terminated by a CRLF pair:

      file% = OPENIN("*.txt")
IF file%=0 ERROR 100, "File could not be opened"
WHILE NOT EOF#file%
INPUT #file%, a$
IF ASCa$=10 a$ = MID$(a$,2)
ENDWHILE
CLOSE #file%

[edit] Bracmat

fil is a relatively low level Bracmat function for manipulating files. Depending on the parameters it opens, closes, reads, writes a file or reads or sets the file position.

  fil$("test.txt",r)    { r opens a text file, rb opens a binary file for reading }
& fil$(,STR,\n) { first argument empty: same as before (i.e. "test.txt") }
{ if \n were replaced by e.g. "\n\t " we would read word-wise instead }
& 0:?lineno
& whl
' ( fil$:(?line.?sep) { "sep" contains found stop character, i.e. \n }
& put$(line (1+!lineno:?lineno) ":" !line \n)
)
& (fil$(,SET,-1)|); { Setting file position before start closes file, and fails.
Therefore the | }

[edit] Brat

include :file
 
file.each_line "foobar.txt" { line |
p line
}

[edit] C

This is not easy to do, because the C library is so primitive.


[edit] Traditional gets(), fgets()

The traditional C library has gets() and fgets(). But fgets() takes a fixed-size destination (so limited line length), and gets() has no destination size check at all (so overwrites memory on long lines). Both have no way to distinguish a \0 within the line from the \0 terminator added to the end of the buffer. Tthey have the advantage of being available everywhere.

#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char buf[256];
while (fgets (buf, sizeof(buf), stdin)) {
printf("line: %s", buf);
}
if (ferror(stdin)) {
fprintf(stderr,"Oops, error reading stdin\n");
abort();
}
return 0;
}

[edit] BSD fgetln()

The next example uses fgetln() and err() from BSD, but will not work with most other systems.

Library: BSD libc
Works with: BSD version 4.4
#include <err.h>	/* err */
#include <stdio.h> /* fopen, fgetln, fputs, fwrite */
 
/*
* Read a file line by line.
* http://rosettacode.org/wiki/Read_a_file_line_by_line
*/

int
main()
{
FILE *f;
size_t len;
char *line;
 
f = fopen("foobar.txt", "r");
if (f == NULL)
err(1, "foobar.txt");
 
/*
* This loop reads each line.
* Remember that line is not a C string.
* There is no terminating '\0'.
*/

while (line = fgetln(f, &len)) {
/*
* Do something with line.
*/

fputs("LINE: ", stdout);
fwrite(line, len, 1, stdout);
}
if (!feof(f))
err(1, "fgetln");
 
return 0;
}

For other systems, you can code something like fgetln(). The next example refactors the code from Synchronous concurrency#C that reads lines.

#include <stdlib.h>	/* exit, malloc, realloc, free */
#include <stdio.h> /* fopen, fgetc, fputs, fwrite */
 
struct line_reader {
/* All members are private. */
FILE *f;
char *buf;
size_t siz;
};
 
/*
* Initializes a line reader _lr_ for the stream _f_.
*/

void
lr_init(struct line_reader *lr, FILE *f)
{
lr->f = f;
lr->buf = NULL;
lr->siz = 0;
}
 
/*
* Reads the next line. If successful, returns a pointer to the line,
* and sets *len to the number of characters, at least 1. The result is
* _not_ a C string; it has no terminating '\0'. The returned pointer
* remains valid until the next call to next_line() or lr_free() with
* the same _lr_.
*
* next_line() returns NULL at end of file, or if there is an error (on
* the stream, or with memory allocation).
*/

char *
next_line(struct line_reader *lr, size_t *len)
{
size_t newsiz;
int c;
char *newbuf;
 
*len = 0; /* Start with empty line. */
for (;;) {
c = fgetc(lr->f); /* Read next character. */
if (ferror(lr->f))
return NULL;
 
if (c == EOF) {
/*
* End of file is also end of last line,
` * unless this last line would be empty.
*/

if (*len == 0)
return NULL;
else
return lr->buf;
} else {
/* Append c to the buffer. */
if (*len == lr->siz) {
/* Need a bigger buffer! */
newsiz = lr->siz + 4096;
newbuf = realloc(lr->buf, newsiz);
if (newbuf == NULL)
return NULL;
lr->buf = newbuf;
lr->siz = newsiz;
}
lr->buf[(*len)++] = c;
 
/* '\n' is end of line. */
if (c == '\n')
return lr->buf;
}
}
}
 
/*
* Frees internal memory used by _lr_.
*/

void
lr_free(struct line_reader *lr)
{
free(lr->buf);
lr->buf = NULL;
lr->siz = 0;
}
 
/*
* Read a file line by line.
* http://rosettacode.org/wiki/Read_a_file_line_by_line
*/

int
main()
{
struct line_reader lr;
FILE *f;
size_t len;
char *line;
 
f = fopen("foobar.txt", "r");
if (f == NULL) {
perror("foobar.txt");
exit(1);
}
 
/*
* This loop reads each line.
* Remember that line is not a C string.
* There is no terminating '\0'.
*/

lr_init(&lr, f);
while (line = next_line(&lr, &len)) {
/*
* Do something with line.
*/

fputs("LINE: ", stdout);
fwrite(line, len, 1, stdout);
}
if (!feof(f)) {
perror("next_line");
exit(1);
}
lr_free(&lr);
 
return 0;
}

[edit] Using mmap()

Implementation using mmap syscall. Works on Linux 2.6.* and on *BSDs. Line reading routine takes a callback function, each line is passed into callback as begin and end pointer. Let OS handle your memory pages, we don't need no stinking mallocs.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <err.h>
 
int read_lines(const char * fname, int (*call_back)(const char*, const char*))
{
int fd = open(fname, O_RDONLY);
struct stat fs;
char *buf, *buf_end;
char *begin, *end, c;
 
if (fd == -1) {
err(1, "open: %s", fname);
return 0;
}
 
if (fstat(fd, &fs) == -1) {
err(1, "stat: %s", fname);
return 0;
}
 
/* fs.st_size could have been 0 actually */
buf = mmap(0, fs.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (buf == (void*) -1) {
err(1, "mmap: %s", fname);
close(fd);
return 0;
}
 
buf_end = buf + fs.st_size;
 
begin = end = buf;
while (1) {
if (! (*end == '\r' || *end == '\n')) {
if (++end < buf_end) continue;
} else if (1 + end < buf_end) {
/* see if we got "\r\n" or "\n\r" here */
c = *(1 + end);
if ( (c == '\r' || c == '\n') && c != *end)
++end;
}
 
/* call the call back and check error indication. Announce
error here, because we didn't tell call_back the file name */

if (! call_back(begin, end)) {
err(1, "[callback] %s", fname);
break;
}
 
if ((begin = ++end) >= buf_end)
break;
}
 
munmap(buf, fs.st_size);
close(fd);
return 1;
}
 
int print_line(const char* begin, const char* end)
{
if (write(fileno(stdout), begin, end - begin + 1) == -1) {
return 0;
}
return 1;
}
 
int main()
{
return read_lines("test.ps", print_line) ? 0 : 1;
}
 

[edit] C++

#include <fstream>
#include <string>
#include <iostream>
 
int main( int argc , char** argv ) {
int linecount = 0 ;
std::string line ;
std::ifstream infile( argv[ 1 ] ) ;
if ( infile ) {
while ( getline( infile , line ) ) {
std::cout << linecount << ": " << line << '\n' ;//supposing '\n' to be line end
linecount++ ;
}
}
infile.close( ) ;
return 0 ;
}
Library: U++
#include <Core/Core.h>
 
using namespace Upp;
 
CONSOLE_APP_MAIN
{
FileIn in(CommandLine()[0]);
while(in && !in.IsEof())
Cout().PutLine(in.GetLine());
}

[edit] C#

'File.ReadLines' reads the lines of a file which could easily be stepped through.

foreach (string readLine in File.ReadLines("FileName")
DoSomething(readLine);

A full code may look like;

using System;
using System.IO;
using System.Text;
 
namespace RosettaCode
{
internal class Program
{
private static void Main()
{
var sb = new StringBuilder();
string F = "File.txt";
 
// Read a file, line by line.
try
{
foreach (string readLine in File.ReadLines(F))
{
// Use the data in some way...
sb.Append(readLine);
sb.Append("\n");
}
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
Environment.Exit(1);
}
 
// Preset the results
Console.WriteLine(sb.ToString());
}
}
}

[edit] Clojure

 
(with-open [r (clojure.java.io/reader "some-file.txt")]
(doseq [l (line-seq r)]
(println l)))
 

[edit] COBOL

       IDENTIFICATION DIVISION.
PROGRAM-ID. read-file-line-by-line.
 
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT input-file ASSIGN TO "input.txt"
ORGANIZATION LINE SEQUENTIAL
FILE STATUS input-file-status.
 
DATA DIVISION.
FILE SECTION.
FD input-file.
01 input-record PIC X(256).
 
WORKING-STORAGE SECTION.
01 input-file-status PIC 99.
88 file-is-ok VALUE 0.
88 end-of-file VALUE 10.
 
01 line-count PIC 9(6).
 
PROCEDURE DIVISION.
OPEN INPUT input-file
IF NOT file-is-ok
DISPLAY "The file could not be opened."
GOBACK
END-IF
 
PERFORM VARYING line-count FROM 1 BY 1 UNTIL end-of-file
READ input-file
DISPLAY line-count ": " FUNCTION TRIM(input-record)
END-PERFORM
 
CLOSE input-file
 
GOBACK
.

[edit] CoffeeScript

Works with: node.js
 
# This module shows two ways to read a file line-by-line in node.js.
fs = require 'fs'
 
# First, let's keep things simple, and do things synchronously. This
# approach is well-suited for simple scripts.
do ->
fn = "read_file.coffee"
for line in fs.readFileSync(fn).toString().split '\n'
console.log line
console.log "DONE SYNC!"
 
# Now let's complicate things.
#
# Use the following code when files are large, and memory is
# constrained and/or where you want a large amount of concurrency.
#
# Protocol:
# Call LineByLineReader, which calls back to you with a reader.
# The reader has two methods.
# next_line: call to this when you want a new line
# close: call this when you are done using the file before
# it has been read completely
#
# When you call next_line, you must supply two callbacks:
# line_cb: called back when there is a line of text
# done_cb: called back when there is no more text in the file
LineByLineReader = (fn, cb) ->
fs.open fn, 'r', (err, fd) ->
bufsize = 256
pos = 0
text = ''
eof = false
closed = false
reader =
next_line: (line_cb, done_cb) ->
if eof
if text
last_line = text
text = ''
line_cb last_line
else
done_cb()
return
 
new_line_index = text.indexOf '\n'
if new_line_index >= 0
line = text.substr 0, new_line_index
text = text.substr new_line_index + 1, text.length - new_line_index - 1
line_cb line
else
frag = new Buffer(bufsize)
fs.read fd, frag, 0, bufsize, pos, (err, bytesRead) ->
s = frag.toString('utf8', 0, bytesRead)
text += s
pos += bytesRead
if (bytesRead)
reader.next_line line_cb, done_cb
else
eof = true
fs.closeSync(fd)
closed = true
reader.next_line line_cb, done_cb
close: ->
# The reader should call this if they abandon mid-file.
fs.closeSync(fd) unless closed
 
cb reader
 
# Test our interface here.
do ->
console.log '---'
fn = 'read_file.coffee'
LineByLineReader fn, (reader) ->
callbacks =
process_line: (line) ->
console.log line
reader.next_line callbacks.process_line, callbacks.all_done
all_done: ->
console.log "DONE ASYNC!"
reader.next_line callbacks.process_line, callbacks.all_done
 

[edit] Common Lisp

(with-open-file (input "file.txt")
(loop for line = (read-line input nil)
while line do (format t "~a~%" line)))

[edit] D

void main() {
import std.stdio;
 
foreach (line; "read_a_file_line_by_line.d".File.byLine)
line.writeln;
}

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.

[edit] Delphi

 
procedure ReadFileByLine;
var
TextFile: text;
TextLine: String;
begin
Assign(TextFile, 'c:\test.txt');
Reset(TextFile);
while not Eof(TextFile) do
Readln(TextFile, TextLine);
CloseFile(TextFile);
end;
 

The example file (above) "c:\test.txt" is assigned to the text file variable "TextFile" is opened and any line is read in a loop into the string variable "TextLine".

 
procedure ReadFileByLine;
var
TextLines : TStringList;
i : Integer;
begin
TextLines := TStringList.Create;
TextLines.LoadFromFile('c:\text.txt');
for i := 0 to TextLines.count -1 do
ShowMessage(TextLines[i]);
end;
 

Above uses the powerful utility classs type TStringList from Classes Unit

See also GNU LGPL (Delphi replacement) Lazarus IDE FreePascal and specifically Lazarus FreePascal Equivalent for TStringList

[edit] Erlang

read_a_file_line_by_line:into_list/1 is used by Read_a_specific_line_from_a_file. If this task is updated keep backwards compatibility, or change Read_a_specific_line_from_a_file, too.

 
-module( read_a_file_line_by_line ).
 
-export( [into_list/1] ).
 
into_list( File ) ->
{ok, IO} = file:open( File, [read] ),
into_list( io:get_line(IO, ''), IO, [] ).
 
 
into_list( eof, _IO, Acc ) -> lists:reverse( Acc );
into_list( {error, _Error}, _IO, Acc ) -> lists:reverse( Acc );
into_list( Line, IO, Acc ) -> into_list( io:get_line(IO, ''), IO, [Line | Acc] ).
 
Output:
6> read_a_file_line_by_line:into_list("read_a_file_line_by_line.erl").
["-module( read_a_file_line_by_line ).\n","\n",
 "-export( [into_list/1] ).\n","\n","into_list( File ) ->\n",
 "\t{ok, IO} = file:open( File, [read] ),\n",
 "\tinto_list( io:get_line(IO, ''), IO, [] ).\n","\n","\n",
 "into_list( eof, _IO, Acc ) -> lists:reverse( Acc );\n",
 "into_list( {error, _Error}, _IO, Acc ) -> lists:reverse( Acc );\n",
 "into_list( Line, IO, Acc ) -> into_list( io:get_line(IO, ''), IO, [Line | Acc] ).\n"]

[edit] Euphoria

constant cmd = command_line()
constant filename = cmd[2]
constant fn = open(filename,"r")
integer i
i = 1
object x
while 1 do
x = gets(fn)
if atom(x) then
exit
end if
printf(1,"%2d: %s",{i,x})
i += 1
end while
close(fn)

Output:

 1: constant cmd = command_line()
 2: constant filename = cmd[2]
 3: constant fn = open(filename,"r")
 4: integer i
 5: i = 1
 6: object x
 7: while 1 do
 8:     x = gets(fn)
 9:     if atom(x) then
10:         exit
11:     end if
12:     printf(1,"%2d: %s",{i,x})
13:     i += 1
14: end while
15: close(fn)


[edit] F#

Using DotNet's System.IO.File.ReadLines iterator:

open System.IO
 
[<EntryPoint>]
let main argv =
File.ReadLines(argv.[0]) |> Seq.iter (printfn "%s")
0

[edit] Factor

 "path/to/file" utf8 [ [ readln dup [ print ] when* ] loop ] with-file-reader

[edit] Fantom

Reads each line from the file "data.txt".

 
class Main
{
Void main ()
{
File (`data.txt`).eachLine |Str line|
{
echo ("Line: $line")
}
}
}
 

[edit] Forth

4096 constant max-line
 
: third ( A b c -- A b c A )
>r over r> swap ;
 
: read-lines ( fileid -- )
begin pad max-line third read-line throw
while pad swap ( fileid c-addr u ) \ string excludes the newline
2drop
repeat 2drop ;

[edit] Frink

The lines function can also take an optional second string argument indicating the encoding of the file, and can read from any supported URL type (HTTP, FTP, etc.)

 
for line = lines["file:yourfile.txt"]
println[line]
 

[edit] GAP

ReadByLines := function(name)
local file, line, count;
file := InputTextFile(name);
count := 0;
while true do
line := ReadLine(file);
if line = fail then
break;
fi;
count := count + 1;
od;
CloseStream(file);
return count;
end;
 
# With [http://www.ibiblio.org/pub/docs/misc/amnesty.txt amnesty.txt]
ReadByLines("amnesty.txt");
# 384

[edit] Go

bufio.Scanner

The bufio package provides Scanner, a convenient interface for reading data such as a file of newline-delimited lines of text. Successive calls to the Scan method will step through the 'tokens' of a file, skipping the bytes between the tokens. The specification of a token is defined by a split function of type SplitFunc; the default split function breaks the input into lines with line termination stripped. Split functions are defined in this package for scanning a file into lines, bytes, UTF-8-encoded runes, and space-delimited words. The client may instead provide a custom split function.

Scanning stops unrecoverably at EOF, the first I/O error, or a token too large to fit in the buffer. When a scan stops, the reader may have advanced arbitrarily far past the last token. Programs that need more control over error handling or large tokens, or must run sequential scans on a reader, should use bufio.Reader instead.

package main
 
import (
"bufio"
"fmt"
"log"
"os"
)
 
func init() {
log.SetFlags(log.Lshortfile)
}
 
func main() {
// Open an input file, exit on error.
inputFile, err := os.Open("byline.go")
if err != nil {
log.Fatal("Error opening input file:", err)
}
 
// Closes the file when we leave the scope of the current function,
// this makes sure we never forget to close the file if the
// function can exit in multiple places.
defer inputFile.Close()
 
scanner := bufio.NewScanner(inputFile)
 
// scanner.Scan() advances to the next token returning false if an error was encountered
for scanner.Scan() {
fmt.Println(scanner.Text())
}
 
// When finished scanning if any error other than io.EOF occured
// it will be returned by scanner.Err().
if err := scanner.Err(); err != nil {
log.Fatal(scanner.Err())
}
}
 
ReadLine

This function allows files to be rapidly scanned for desired data while minimizing memory allocations. It also handles /r/n line endings and allows unreasonably long lines to be handled as error conditions.

package main
 
import (
"bufio"
"fmt"
"io"
"log"
"os"
)
 
func main() {
f, err := os.Open("file") // os.OpenFile has more options if you need them
if err != nil { // error checking is good practice
// error *handling* is good practice. log.Fatal sends the error
// message to stderr and exits with a non-zero code.
log.Fatal(err)
}
 
// os.File has no special buffering, it makes straight operating system
// requests. bufio.Reader does buffering and has several useful methods.
bf := bufio.NewReader(f)
 
// there are a few possible loop termination
// conditions, so just start with an infinite loop.
for {
// reader.ReadLine does a buffered read up to a line terminator,
// handles either /n or /r/n, and returns just the line without
// the /r or /r/n.
line, isPrefix, err := bf.ReadLine()
 
// loop termination condition 1: EOF.
// this is the normal loop termination condition.
if err == io.EOF {
break
}
 
// loop termination condition 2: some other error.
// Errors happen, so check for them and do something with them.
if err != nil {
log.Fatal(err)
}
 
// loop termination condition 3: line too long to fit in buffer
// without multiple reads. Bufio's default buffer size is 4K.
// Chances are if you haven't seen a line terminator after 4k
// you're either reading the wrong file or the file is corrupt.
if isPrefix {
log.Fatal("Error: Unexpected long line reading", f.Name())
}
 
// success. The variable line is now a byte slice based on on
// bufio's underlying buffer. This is the minimal churn necessary
// to let you look at it, but note! the data may be overwritten or
// otherwise invalidated on the next read. Look at it and decide
// if you want to keep it. If so, copy it or copy the portions
// you want before iterating in this loop. Also note, it is a byte
// slice. Often you will want to work on the data as a string,
// and the string type conversion (shown here) allocates a copy of
// the data. It would be safe to send, store, reference, or otherwise
// hold on to this string, then continue iterating in this loop.
fmt.Println(string(line))
}
}
ReadString

In comparison, ReadString is a little quick and dirty, but is often good enough.

package main
 
import (
"bufio"
"fmt"
"io"
"log"
"os"
)
 
func main() {
f, err := os.Open("file")
if err != nil {
log.Fatal(err)
}
bf := bufio.NewReader(f)
for {
switch line, err := bf.ReadString('\n'); err {
case nil:
// valid line, echo it. note that line contains trailing \n.
fmt.Print(line)
case io.EOF:
if line > "" {
// last line of file missing \n, but still valid
fmt.Println(line)
}
return
default:
log.Fatal(err)
}
}
}

[edit] Groovy

new File("Test.txt").eachLine { line, lineNumber ->
println "processing line $lineNumber: $line"
}


[edit] Haskell

Thanks to laziness, there's no difference between reading the file all at once and reading it line by line.

main = do
file <- readFile "linebyline.hs"
mapM_ putStrLn (lines file)
 

[edit] Icon and Unicon

Line oriented I/O is basic. This program reads lines from "input.txt" into the variable line, but does nothing with it.

procedure main()
f := open("input.txt","r") | stop("cannot open file ",fn)
while line := read(f)
close(f)
end

[edit] 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 separator 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.

cocurrent 'linereader'
 
NB. configuration parameter
blocksize=: 400000
 
NB. implementation
offset=: 0
position=: 0
buffer=: ''
lines=: ''
 
create=: monad define
name=: boxxopen y
size=: 1!:4 name
blocks=: 2 <@(-~/\)\ ~. size <. blocksize * i. 1 + >. size % blocksize
)
 
readblocks=: monad define
if. 0=#blocks do. return. end.
if. 1<#lines do. return. end.
whilst. -.LF e.chars do.
buffer=: buffer,chars=. 1!:11 name,{.blocks
blocks=: }.blocks
lines=: <;._2 buffer,LF
end.
buffer=: _1{::lines
)
 
next=: monad define
if. (#blocks)*.2>#lines do. readblocks'' end.
r=. 0{::lines
lines=: }.lines
r
)
   example=: '/tmp/example.txt' conew 'linereader'
next__example''
this is line 1
next__example''
and this is line 2

[edit] Java

import java.io.BufferedReader;
import java.io.FileReader;
 
/**
* Reads a file line by line, processing each line.
*
* @author $Author$
* @version $Revision$
*/

public class ReadFileByLines {
private static void processLine(int lineNo, String line) {
// ...
}
 
public static void main(String[] args) {
for (String filename : args) {
BufferedReader br = null;
FileReader fr = null;
try {
fr = new FileReader(filename);
br = new BufferedReader(fr);
String line;
int lineNo = 0;
while ((line = br.readLine()) != null) {
processLine(++lineNo, line);
}
}
catch (Exception x) {
x.printStackTrace();
}
finally {
if (fr != null) {
try {br.close();} catch (Exception ignoreMe) {}
try {fr.close();} catch (Exception ignoreMe) {}
}
}
}
}
}
Works with: Java version 7+

In Java 7, the try with resources block handles multiple readers and writers without nested try blocks. The loop in the main method would look like this:

for (String filename : args) {
try (FileReader fr = new FileReader(filename);BufferedReader br = new BufferedReader(fr)){
String line;
int lineNo = 0;
while ((line = br.readLine()) != null) {
processLine(++lineNo, line);
}
}
catch (Exception x) {
x.printStackTrace();
}
}

fr and br are automatically closed when the program exits the try block (it also checks for nulls before closing and throws closing exceptions out of the block).

A more under-the-hood method in Java 7 would be to use the Files class (line numbers can be inferred from indices in the returned List):

import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.charset.Charset;
import java.io.IOException;
//...other class code
List<String> lines = null;
try{
lines = Files.readAllLines(Paths.get(filename), Charset.defaultCharset());
}catch(IOException | SecurityException e){
//problem with the file
}

[edit] Julia

open("input_file","r") do f
for line in eachline(f)
println("read line: ", line)
end
end

[edit] Lasso

local(f) = file('foo.txt')
handle => {#f->close}
#f->forEachLine => {^
#1
'<br>' // note this simply inserts an HTML line break between each line.
^}

[edit] Liberty BASIC

filedialog "Open","*.txt",file$
if file$="" then end
open file$ for input as #f
while not(eof(#f))
line input #f, t$
print t$
wend
close #f

Mac

filedialog "Open","*.txt",file$
if file$="" then end
open file$ for input as #f
while not(eof(#f))
t$ = inputto$(#f, chr$(13))
print t$
wend
close #f

Unix

filedialog "Open","*.txt",file$
if file$="" then end
open file$ for input as #f
while not(eof(#f))
t$ = inputto$(#f, chr$(10))
print t$
wend
close #f

[edit]

There are several words which will return a line of input.

  • readline - returns a line as a list of words
  • readword - returns a line as a single word, or an empty list if it reached the end of file
  • readrawline - returns a line as a single word, with no characters escaped
while [not eof?] [print readline]

[edit] Lua

filename = "input.txt"
fp = io.open( filename, "r" )
 
for line in fp:lines() do
print( line )
end
 
fp:close()
 

[edit] Mathematica

 
strm=OpenRead["input.txt"];
If[strm=!=$Failed,
While[line=!=EndOfFile,
line=Read[strm];
(*Do something*)
]];
Close[strm];
 

[edit] MATLAB / Octave

The function fgetl() read lines from file:

 
fid = fopen('foobar.txt','r');
if (fid < 0)
printf('Error:could not open file\n')
else
while ~feof(fid),
line = fgetl(fid);
%% process line %%
end;
fclose(fid)
end;

[edit] Maxima

/* Read a file and return a list of all lines */
 
readfile(name) := block(
[v: [ ], f: openr(name), line],
while stringp(line: readline(f)) do v: endcons(line, v),
close(f),
v
)$

[edit] NetRexx

[edit] Using Java Scanner

/* NetRexx */
options replace format comments java crossref symbols nobinary
 
parse arg inFileName .
 
if inFileName = '' | inFileName = '.' then inFileName = './data/dwarfs.json'
lines = scanFile(inFileName)
loop l_ = 1 to lines[0]
say l_.right(4)':' lines[l_]
end l_
 
return
 
-- Read a file and return contents as a Rexx indexed string
method scanFile(inFileName) public static returns Rexx
 
fileLines = ''
do
inFile = File(inFileName)
inFileScanner = Scanner(inFile)
loop l_ = 1 while inFileScanner.hasNext()
fileLines[0] = l_
fileLines[l_] = inFileScanner.nextLine()
end l_
inFileScanner.close()
 
catch ex = FileNotFoundException
ex.printStackTrace
end
 
return fileLines
 

[edit] Using Java Reader

/* NetRexx */
options replace format comments java crossref symbols nobinary
 
parse arg inFileName .
 
if inFileName = '' | inFileName = '.' then inFileName = './data/dwarfs.json'
lines = readFile(inFileName)
loop l_ = 1 to lines[0]
say l_.right(4)':' lines[l_]
end l_
 
return
 
-- Read a file and return contents as a Rexx indexed string
method readFile(inFileName) public static returns Rexx
 
fileLines = ''
inLine = String null
inFileBR = BufferedReader null
 
do
inFile = File(inFileName)
inFileBR = BufferedReader(FileReader(inFile))
loop l_ = 1 until inline = null
inLine = inFileBR.readLine()
if inline \= null then do
fileLines[0] = l_
fileLines[l_] = inLine
end
end l_
 
catch exFNF = FileNotFoundException
exFNF.printStackTrace
catch exIO = IOException
exIO.printStackTrace
finally
if inFileBR \= null then do
do
inFileBR.close()
catch ex = IOException
ex.printStackTrace
end
end
end
 
return fileLines
 

[edit] NewLISP

 
(set 'in-file (open "filename" "read"))
(while (read-line in-file)
(write-line))
(close in-file)

[edit] Nimrod

var i = open("input.txt")
for line in i.lines:
process(line)
i.close()

[edit] Objeck

 
bundle Default {
class ReadFile {
function : Main(args : String[]) ~ Nil {
f := IO.FileReader->New("in.txt");
if(f->IsOpen()) {
string := f->ReadString();
while(f->IsEOF() = false) {
string->PrintLine();
string := f->ReadString();
};
f->Close();
};
}
}
}
 

[edit] Objective-C

To read an entire file into a string, you can:

NSString *path = [NSString stringWithString:@"/usr/share/dict/words"];
NSError *error = nil;
NSString *words = [[NSString alloc] initWithContentsOfFile:path
encoding:NSUTF8StringEncoding error:&error];
 

Use the UTF-8 encoder on ASCII.

Now to get the individual lines, break down the string:

NSArray* lines = [words componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

[edit] OCaml

let () =
let ic = open_in "input.txt" in
try
while true do
let line = input_line ic in
print_endline line
done
with End_of_file ->
close_in ic

But if we want to write a functional loading function we should remember that the try/with couple breaks the tail recursion. So we should externalise it outside of the loop in another function:

let input_line_opt ic =
try Some (input_line ic)
with End_of_file -> None
 
let read_lines ic =
let rec aux acc =
match input_line_opt ic with
| Some line -> aux (line::acc)
| None -> (List.rev acc)
in
aux []
 
let lines_of_file filename =
let ic = open_in filename in
let lines = read_lines ic in
close_in ic;
(lines)

we use it like this:

let () =
let lines = lines_of_file "unixdict.txt" in
List.iter print_endline lines

[edit] OxygenBasic

The core function GetFile reads the whole file:

 
function getline(string s, sys *i, *el) as string
sys e
e=instr i,s,chr(el)
if e=0 then
el=10
e=instr i,s,chr(el) 'files not using chr 13
end if
if e=0 then e=len s
e++
if el=13 then
if asc(s,e)=10 then e++ 'crlf
end if
function = mid s,i,e-i
i=e
end function
 
'=====
'TEST:
'=====
 
s=getfile "t.txt"
i=1
wr=""
c=0
el=13
do
wr = getline s,i,el
if wr="" then exit do
'print wr
c++
end do
print "Line count " c
 

[edit] PARI/GP

GP has an unfortunate limitations that prevents reading files line-by-line, but it's just as well since its file-handling capabilities are poor. The TODO file lists one desiderata as adding a t_FILE, which if added would presumably have support for this sort of operation.

Thus the usual way of interacting with files in more than the simple way allowed by read is done by PARI with the usual C commands:

FILE *f = fopen(name, "r");
if (!f) {
pari_err(openfiler, "input", name);
}
while(fgets(line, MAX_LINELEN, f) != NULL) {
// ...
}

[edit] Pascal

See Delphi

[edit] Perl

For the simple case of iterating over the lines of a file you can do:

open(my $fh, '<', 'foobar.txt')
|| die "Could not open file: $!";
while (<$fh>)
{ # each line is stored in $_, with terminating newline
# chomp, short for chomp($_), removes the terminating newline
chomp;
process($_);
}
close $fh;

File encoding can be specified like:

open(my $fh, '< :encoding(UTF-8)', 'foobar.txt')
|| die "Could not open file: $!";

The angle bracket operator < > reads a filehandle line by line. (The angle bracket operator can also be used to open and read from files that match a specific pattern, by putting the pattern in the brackets.)

Without specifying the variable that each line should be put into, it automatically puts it into $_, which is also conveniently the default argument for many Perl functions. If you wanted to use your own variable, you can do something like this:

open(my $fh, '<', 'foobar.txt')
|| die "Could not open file: $!";
while (my $line = <$fh>)
{
chomp $line;
process($line);
}
close $fh;

The special use of the angle bracket operator with nothing inside, will read from all files whose names were specified on the command line:

while (<>) {
chomp;
process($_);
}

As noted in perlop.pod under "I/O Operators", <> opens with the 2-arg open() and so can read from a piped command. This can be convenient but is also very much insecure--a user could supply a file with the name like

perl myscript.pl 'rm -rf / |'

or any other arbitrary command, which will be executed when perl attempts to open a pipe for it. As such, this feature is best reserved for one-liners and is bad practice to use in production code. The same is true for the open(FILEHANDLE, EXPR) form of open as opposed to open(FILEHANDLE, MODE, EXPR). (See perlfunc.pod on the open() function.)

The ARGV::readonly module can defang @ARGV by modifying the names to ensure they are treated only as files by the open().

The readline function can be used instead of < >:

open(my $fh, '<', 'foobar.txt') or die "$!";
while (readline $fh)
{ ... }
 
while (my $line = readline $fh)
{ ... }
close $fh;

The readline function is the internal function used to implement < >, but can be used directly and is useful for conveying programmer intent in certain situations.

[edit] Perl 6

The lines method is lazy so the following code does indeed read the file line by line, and not all at once.

for open('test.txt').lines
{
.say
}

In order to be more explicit about the file being read on line at a time, one can write:

my $f = open 'test.txt';
while my $line = $f.get {
say $line;
}

[edit] PicoLisp

(in "foobar.txt"
(while (line)
(process @) ) )

[edit] PHP

<?php
$file = fopen(__FILE__, 'r'); // read current file
while ($line = fgets($file)) {
$line = rtrim($line); // removes linebreaks and spaces at end
echo strrev($line) . "\n"; // reverse line and upload it
}
<?php // HOW TO ECHO FILE LINE BY LINE FROM THE COMMAND LINE: php5-cli
$file = fopen('test.txt', 'r'); // OPEN FILE WITH READ ACCESS
while (!feof($file)) {
$line = rtrim(fgets($file)); // REMOVE TRAILING WHITESPACE AND GET LINE
if($line != NULL) echo("$line\n"); // IF THE LINE ISN'T NULL, ECHO THE LINE
}

[edit] PL/I

 
read: procedure options (main);
declare line character (500) varying;
 
on endfile (sysin) stop;
 
do forever;
get edit (line)(L);
end;
end read;
 

[edit] PowerShell

$reader = [System.IO.File]::OpenText($mancorfile)
try {
do {
$line = $reader.ReadLine()
if ($line -eq $null) { break }
DoSomethingWithLine($line)
} while ($TRUE)
} finally {
$reader.Close()
}
 

[edit] PureBasic

FileName$ = OpenFileRequester("","foo.txt","*.txt",0)
 
If OpenFile(0, FileName$)
While Not Eof(0)
line$ = ReadString(0)
DoSomethingWithTheLine(Line)
Wend
CloseFile(0)
EndIf

[edit] Python

For the simple case of iterating over the lines of a file you can do:

with open("foobar.txt") as f:
for line in f:
process(line)

The with statement ensures the correct closing of the file after it is processed, and iterating over the file object f, adjusts what is considered line separator character(s) so the code will work on multiple operating systems such as Windows, Mac, and Solaris without change.
Any exceptional conditions seen when processing the file will raise an exception. Leaving the while loop because of an exception will also cause the file to be correctly closed on the way.

Python also has the fileinput module. This can process multiple files parsed from the command line and can be set to modify files 'in-place'.

import fileinput
for line in fileinput.input():
process(line)
 

[edit] R

conn <- file("notes.txt", "r")
while(length(line <- readLines(conn, 1)) > 0) {
cat(line, "\n")
}

[edit] Racket

(define (read-next-line-iter file)
(let ((line (read-line file)))
(unless (eof-object? line)
(display line)
(newline)
(read-next-line-iter file))))
(call-with-input-file "foobar.txt" read-next-line-iter)

[edit] REXX

/*REXX program to read and display (with count) a file, one line at a time.*/
parse arg fileID .
say 'Displaying file:' fileID
 
do linenumber=1 while lines(fileID)\==0 /* loop construct */
line=linein(fileID) /* read line */
say 'Line' linenumber':' line /* show line number and line */
end linenumber /* end loop and confirm which loop */
 
say
say 'File' fileID 'has' linenumber-1 'lines.' /*summary.*/

Or: the 'known name' short version:

file='foobar.txt'
do while lines(file)\==0; say linein(file); end

[edit] Ruby

IO.foreach "foobar.txt" do |line|
# Do something with line.
puts line
end
# File inherits from IO, so File.foreach also works.
File.foreach("foobar.txt") {|line| puts line}
# IO.foreach and File.foreach can also read a subprocess.
IO.foreach "| grep afs3 /etc/services" do |line|
puts line
end

Caution! IO.foreach and File.foreach take a portname. To open an arbitrary filename (which might start with "|"), you must use File.open, then IO#each (or IO#each_line). The block form of File.open automatically closes the file after running the block.

filename = "|strange-name.txt"
File.open(filename) do |file|
file.each {|line| puts line}
end

[edit] Run BASIC

open DefaultDir$ + "\public\filetest.txt" for input as #f
while not(eof(#f))
line input #f, a$
print a$
wend
close #f
 

[edit] Scala

import scala.io._
Source.fromFile("foobar.txt").getLines.foreach(println)

[edit] Scheme

; Commented line below should be uncommented to use read-line with Guile
;(use-modules (ice-9 rdelim))
 
(define file (open-input-file "input.txt"))
(do ((line (read-line file) (read-line file))) ((eof-object? line))
(display line)
(newline))

[edit] Sed

Through a .sed file:

#!/bin/sed -f
p
 

or through a one-liner in bash:

 
sed p filename
 

[edit] Seed7

$ include "seed7_05.s7i";
 
const proc: main is func
local
var file: aFile is STD_NULL;
var string: line is "";
begin
aFile := open("input.txt", "r");
while hasNext(aFile) do
readln(aFile, line);
writeln("LINE: " <& line);
end while;
end func;

The function hasNext returns TRUE when at least one character can be read successfully.

[edit] Sidef

FileHandle.each{} is lazy, so we can do this:

File.new(__FILE__).open_r.each { |line|
print line;
}

Same thing explicitly:

var fh = File.new(__FILE__).open_r;
while (fh.readline(&var line)) {
print line;
}

[edit] Smalltalk

Works with: Pharo
 
(StandardFileStream oldFileNamed: 'test.txt') contents lines do: [  :each | Transcript show: each. ]
 
Works with: Smalltalk/X
'foobar.txt' asFilename readingLinesDo:[:eachLine | eachLine printCR]

alternatively:

|s|
s := 'foobar.txt' asFilename readStream.
[ s atEnd ] whileFalse:[
s nextLine printCR.
].
s close

alternatively:

'foobar.txt' asFilename contents do:[:eachLine | eachLine printCR].

[edit] SNOBOL4

In SNOBOL4, file I/O is done by associating a file with a variable. Every subsequent access to the variable provides the next record of the file. Options to the input() function allow the file to be opened in line mode, fixed-blocksize (raw binary) mode, and with various sharing options. The input() operation generally fails (in most modern implementations) if the file requested is not found (in earlier implementations, that failure is reported the same way as end-of-file when the first actual read from the file is attempted). You can specify the file unit number to use (a vestigial remnant of the Fortran I/O package used by original Bell Labs SNOBOL4 implementations... in this case, I'll use file unit 20). Accessing the variable fails (does not succeed) when the end of file is reached.

        input(.infile,20,"readfrom.txt")      :f(end)
rdloop output = infile  :s(rdloop)
end

[edit] Sparkling

let f = fopen("foo.txt", "r");
if f != nil {
var line;
while (line = fgetline(f)) != nil {
print(line);
}
 
fclose(f);
}

[edit] Tcl

set f [open "foobar.txt"]
while {[gets $f line] >= 0} {
# This loops over every line
puts ">>$line<<"
}
close $f

[edit] TorqueScript

Read a file line by line:

 
//Create a file object
 
%f = new fileObject();
 
//Open and read a file
 
%f.openForRead("PATH/PATH.txt");
 
while(!%f.isEOF())
{
//Read each line from our file
 
%line = %f.readLine();
}
 
//Close the file object
 
%f.close();
 
//Delete the file object
 
%f.delete();
 

[edit] TUSCRIPT

 
$$ MODE TUSCRIPT
 
datei="rosetta.txt"
ERROR/STOP OPEN (datei,READ,-std-)
 
ACCESS q: READ/RECORDS/UTF8 $datei s,line
LOOP
READ/NEXT/EXIT q
PRINT line
ENDLOOP
ENDACCESS q
 

or:

 
LOOP line=datei
PRINT line
ENDLOOP
 

[edit] UNIX Shell

Redirect standard input from a file, and then use IFS= read -r line to read each line.

mksh(1) manual says, "If read is run in a loop such as while read foo; do ...; done then leading whitespace will be removed (IFS) and backslashes processed. You might want to use while IFS= read -r foo; do ...; done for pristine I/O."
Works with: Almquist Shell
# This while loop repeats for each line of the file.
# This loop is inside a pipeline; many shells will
# run this loop inside a subshell.
cat input.txt |
while IFS= read -r line ; do
printf '%s\n' "$line"
done
Works with: Almquist Shell
# This loop runs in the current shell, and can read both
# the old standard input (fd 1) and input.txt (fd 3).
exec 3<input.txt
while IFS= read -r line <&3 ; do
printf '%s\n' "$line"
done
exec 3>&-
Works with: Bourne Shell
# The old Bourne Shell interprets 'IFS= read' as 'IFS= ; read'.
# It requires extra code to restore the original value of IFS.
exec 3<input.txt
oldifs=$IFS
while IFS= ; read -r line <&3 ; do
IFS=$oldifs
printf '%s\n' "$line"
done
IFS=$oldifs
exec 3>&-

[edit] Vala

Reads and prints out file line by line:

 
public static void main(){
var file = FileStream.open("foo.txt", "r");
 
string line = file.read_line();
while (line != null){
stdout.printf("%s\n", line);
line = file.read_line();
}
}
 

[edit] Vedit macro language

On Vedit, you do not actually read file line by line. File reading and writing is handled by automatic file buffering while you process the file.

This example reads the source code of this macro, copies it line by line into a new buffer and adds line numbers.

File_Open("line_by_line.vdm")
#10 = Buf_Num // edit buffer for input file
#11 = Buf_Free // edit buffer for output
#1 = 1 // line number
while (!At_EOF) {
Reg_Copy(20,1) // read one line into text register 20
Buf_Switch(#11) // switch to output file
Num_Ins(#1++, NOCR) // write line number
Ins_Text(" ")
Reg_Ins(20) // write the line
Buf_Switch(#10) // switch to input file
Line(1) // next line
}
Buf_Close(NOMSG) // close the input file
Buf_Switch(#11) // show the output

Output:

    1  File_Open("line_by_line.vdm")
    2  #10 = Buf_Num                   // edit buffer for input file
    3  #11 = Buf_Free                  // edit buffer for output
    4  #1 = 1                          // line number
    5  while (!At_EOF) {
    6      Reg_Copy(20,1)              // read one line into text register 20
    7      Buf_Switch(#11)             // switch to output file
    8      Num_Ins(#1++, NOCR)         // write line number
    9      Ins_Text("  ")
   10      Reg_Ins(20)                 // write the line
   11      Buf_Switch(#10)             // switch to input file
   12      Line(1)                     // next line
   13  }
   14  Buf_Close(NOMSG)                // close the input file
   15  Buf_Switch(#11)                 // show the output

[edit] Visual Basic

' Read lines from a file
'
' (c) Copyright 1993 - 2011 Mark Hobley
'
' This code was ported from an application program written in Microsoft Quickbasic
'
' This code can be redistributed or modified under the terms of version 1.2 of
' the GNU Free Documentation Licence as published by the Free Software Foundation.

Sub readlinesfromafile()
var.filename = "foobar.txt"
var.filebuffersize = ini.inimaxlinelength
Call openfileread
If flg.error = "Y" Then
flg.abort = "Y"
Exit Sub
End If
If flg.exists <> "Y" Then
flg.abort = "Y"
Exit Sub
End If
readfilelabela:
Call readlinefromfile
If flg.error = "Y" Then
flg.abort = "Y"
Call closestream
flg.error = "Y"
Exit Sub
End If
If flg.endoffile <> "Y" Then
' We have a line from the file
Print message$
GoTo readfilelabela
End If
' End of file reached
' Close the file and exit
Call closestream
Exit Sub
End Sub
 
Sub openfileread()
flg.streamopen = "N"
Call checkfileexists
If flg.error = "Y" Then Exit Sub
If flg.exists <> "Y" Then Exit Sub
Call getfreestream
If flg.error = "Y" Then Exit Sub
var.errorsection = "Opening File"
var.errordevice = var.filename
If ini.errortrap = "Y" Then
On Local Error GoTo openfilereaderror
End If
flg.endoffile = "N"
Open var.filename For Input As #var.stream Len = var.filebuffersize
flg.streamopen = "Y"
Exit Sub
openfilereaderror:
var.errorcode = Err
Call errorhandler
resume '!!
End Sub
 
Public Sub checkfileexists()
var.errorsection = "Checking File Exists"
var.errordevice = var.filename
If ini.errortrap = "Y" Then
On Local Error GoTo checkfileexistserror
End If
flg.exists = "N"
If Dir$(var.filename, 0) <> "" Then
flg.exists = "Y"
End If
Exit Sub
checkfileexistserror:
var.errorcode = Err
Call errorhandler
End Sub
 
Public Sub getfreestream()
var.errorsection = "Opening Free Data Stream"
var.errordevice = ""
If ini.errortrap = "Y" Then
On Local Error GoTo getfreestreamerror
End If
var.stream = FreeFile
Exit Sub
getfreestreamerror:
var.errorcode = Err
Call errorhandler
resume '!!
End Sub
 
Sub closestream()
If ini.errortrap = "Y" Then
On Local Error GoTo closestreamerror
End If
var.errorsection = "Closing Stream"
var.errordevice = ""
flg.resumenext = "Y"
Close #var.stream
If flg.error = "Y" Then
flg.error = "N"
'!! Call unexpectederror
End If
flg.streamopen = "N"
Exit Sub
closestreamerror:
var.errorcode = Err
Call errorhandler
resume next
End Sub
 
Public Sub errorhandler()
tmp$ = btrim$(var.errorsection)
tmp2$ = btrim$(var.errordevice)
If tmp2$ <> "" Then
tmp$ = tmp$ + " (" + tmp2$ + ")"
End If
tmp$ = tmp$ + " : " + Str$(var.errorcode)
tmp1% = MsgBox(tmp$, 0, "Error!")
flg.error = "Y"
If flg.resumenext = "Y" Then
flg.resumenext = "N"
' Resume Next
Else
flg.error = "N"
' Resume
End If
End Sub
 
Public Function btrim$(arg$)
btrim$ = LTrim$(RTrim$(arg$))
End Function

[edit] Visual Basic .NET

Imports System.IO
 
' Loop through the lines of a file.
' Function assumes that the file exists.
Private Sub ReadLines(ByVal FileName As String)
 
Dim oReader As New StreamReader(FileName)
Dim sLine As String = Nothing
 
While Not oReader.EndOfStream
sLine = oReader.ReadLine()
' Do something with the line.
End While
 
oReader.Close()
 
End Sub

[edit] Wart

with infile "x"
drain (read_line)

[edit] zkl

So many ways, here are a few

foreach line in (File("foo.zkl")){print(line)}
File("foo.zkl").pump(Console.print)
Utils.zipWith(False,fcn(a,b){"%d: %s".fmt(a,b).print()},
[0..],File("foo.zkl","r"))
-->
0: var R; n:=GarbageMan.gcCount;
1: ref := GarbageMan.WeakRef(String("the","quick brown fox"));
...
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox