{ From: tfiske@delphi.com (Todd Fiske) I've got a huge unit that I've put together over the years that does this, but I'm not really ready to part with it. I'm happy to trade some tips though. The easiest way to start is with text files under 64K, for which you don't have to worry about lines crossing the buffer boundary. Get the size of the file, then allocate an array on the heap of that size and blockread the file into it. Then use a function that reads from the current position up to the next CR and/or LF and returns all of that as a string. Here's a simple example of this: {------------------------------------------------} {- bintext.pas - binary text file example -} {- Todd Fiske (tfiske@delphi.com) - 09/28/1994 -} {------------------------------------------------} program bintext; uses dos; const CR = #13; LF = #10; {------------------------------------------------} {- input structure definition & base routines -} {------------------------------------------------} type big_array = array[0..65519] of byte; big_ptr = ^big_array; input_buffer = record data : big_ptr; size : word; curr : word; end; input_ptr = ^input_buffer; procedure start_input(var i : input_ptr; size : word); begin if i = nil then begin new(i); { create structure } i^.size := size; GetMem(i^.data, i^.size); { create array (could test MemAvail) } fillchar(i^.data^, i^.size, 0); { initialize } i^.curr := 0; end; end; procedure stop_input(var i : input_ptr); begin if i <> nil then begin FreeMem(i^.data, i^.size); { done with array } dispose(i); { done with structure } i := nil; end; end; procedure load_input(i : input_ptr; s : string); var f : file; begin assign(f, s); { set filename } reset(f, 1); { open with record length 1 } blockread(f, i^.data^, i^.size); { read in file - should test IOResult } close(f); end; {------------------------------------------------} {- low level access routines -} {------------------------------------------------} function curr_char(i : input_ptr) : char; begin curr_char := char(i^.data^[i^.curr]); end; procedure next_char(i : input_ptr); begin inc(i^.curr); end; function curr_pos(i : input_ptr) : word; begin curr_pos := i^.curr; end; function end_of_input(i : input_ptr) : boolean; begin end_of_input := i^.curr >= i^.size; end; {------------------------------------------------} {- medium level access -} {------------------------------------------------} function get_line(i : input_ptr) : string; var w : string; stt : word; len : byte; begin stt := curr_pos(i); while (not (curr_char(i) in [CR, LF])) and (not end_of_input(i)) do next_char(i); {- testing for both CR and LF here allows reading of Unix files -} len := curr_pos(i) - stt; { determine length read } move(i^.data^[stt], w[1], len); { copy into work string } w[0] := char(len); { set work string length } if curr_char(i) = CR then next_char(i); { skip line-end chars } if curr_char(i) = LF then next_char(i); get_line := w; { return work string } end; {------------------------------------------------} {- main program -} {------------------------------------------------} var sr : SearchRec; i : input_ptr; line : string; begin writeln; writeln('BinText - binary textfile example'); if paramcount = 0 then begin { check command line } writeln; writeln('usage: bintext '); halt; end; FindFirst(paramstr(1), AnyFile, sr); { test input file } if DOSError <> 0 then begin writeln(paramstr(1), ' not found'); halt; end; if sr.size > 65520 then begin writeln(sr.name, ' : ', sr.size, ' bytes - too big (65520 bytes max)'); halt; end; i := nil; { load, read, and close } start_input(i, sr.size); load_input(i, sr.name); while not end_of_input(i) do begin line := get_line(i); writeln(line); end; stop_input(i); end. {------------------------------------------------} {- eof -} {------------------------------------------------} { This array-of-char file handling can be very flexible. I've included routines in my own to do things like skip whitespace, skip while in a particular groups of characters, skip until in a group of characters, get-while and get-until routines, etc. Another thing you can do is save the byte start position of each line, and jump right to that line by setting i^.curr. What's more, the same basic methods work on binary files as well. }