Recent

Author Topic: new feature request read random line number of data from The text file in to var  (Read 574 times)

januszchmiel

  • New Member
  • *
  • Posts: 15
Dear most advanced elite Pascal developers among us.
I would like to kindly ask you for new procedure.
The aim of this procedure would be to read line of text from text file by specifiing line number.
For example
Procedure Readlnr (linenumber: Real;, linecontent, String;
)
File would had to be opened before, sure.
And user could add line number which would be automatically read from text file.
The problem is, if this procedure could be constructed by calling some Android system calls.
Because procedure should not automatically read whole file and cutting specified line from The big long variable. Because theoretically, file could have many MB in syze.
Is it possible to construct such procedure, which would only really read The specified line number of text in to variable with no need to read whole file first to one big variable, and cutting specified line from this big variable.The Autohotkey C language interpreter for Windows contain this routine.
User can specify file name,line number, variable.
Sure, I did not analysed C source code of autohotkey how this feature work.
If C code read big file in to one variable and other its part cut for example line 20 or 100 of text from The previously readed variable.
Second problem is, if Microsoft di not release some specific Windows procedure for such task and if it can be simply made for Pascal and Android operating system.
Or if Assembly language would had to be used for such task?
But I AM hoping, that not.

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Is it possible to construct such procedure, which would only really read The specified line number of text in to variable with no need to read whole file first

In order to know on which line you are, you need to open the file, read the content, and keep track of the line-endings (on what line are you currently).
So, you cannot simply "jump" to line nr. X.
Potentialy thre are no line-endings in the file at all, and in that case you do have to read the file until the end.

Old school reading of a text file would be the most simple solution.
You read the text line by line (with Readln) and keep count of the line number.
You do need to check wether you are at the end of the file though.

Pseudocode
Code: Pascal  [Select][+][-]
  1.   Assign(TheFile, TheFileName);
  2.   LineNr := 0;
  3.   Reset(TheFile);
  4.   while not EOF(TheFile) do
  5.   begin
  6.     Readln(TheFile,TheString);
  7.     Inc(LineNr);
  8.     if LineNr = LineNrYouAreLookinFor then Break;
  9.   end;
  10.   Close(TheFile);
  11.   if LineNr = LineNrYouAreLookinFor then
  12.     Result := TheString //success
  13.   else
  14.     Result := ''

This of course makes the Result ambiguous if it is an empty string (the file may contain an empty line at th eline number you want).
I'll leave it as an exercise to you to come up with a solution for that.

Bart

loaded

  • Hero Member
  • *****
  • Posts: 824
The Autohotkey C language interpreter for Windows contain this routine.
So how's the speed?
What is the speed difference between reading the entire file and doing the line operations yourself?
How many GB files are you talking about?
In my experience, reading large files with stream methods (especially TReadBufStream) is now very easy!
« Last Edit: March 04, 2023, 03:29:51 pm by loaded »
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

PascalDragon

  • Hero Member
  • *****
  • Posts: 5448
  • Compiler Developer
I would like to kindly ask you for new procedure.
The aim of this procedure would be to read line of text from text file by specifiing line number.
For example
Procedure Readlnr (linenumber: Real;, linecontent, String;
)
File would had to be opened before, sure.
And user could add line number which would be automatically read from text file.

The Pascal file API or more precisely what's used to implement it is not suitable for this, so no. But you can simply do this by yourself, by doing a ReadLn in a loop and increasing a counter and processing each line along the way.

Is it possible to construct such procedure, which would only really read The specified line number of text in to variable with no need to read whole file first to one big variable, and cutting specified line from this big variable.The Autohotkey C language interpreter for Windows contain this routine.
User can specify file name,line number, variable.
Sure, I did not analysed C source code of autohotkey how this feature work.
If C code read big file in to one variable and other its part cut for example line 20 or 100 of text from The previously readed variable.

The code still needs to read the file line by line and maybe discard lines. Just implement it yourself.

Second problem is, if Microsoft di not release some specific Windows procedure for such task and if it can be simply made for Pascal and Android operating system.
Or if Assembly language would had to be used for such task?

Assembly has nothing to do with that. This can be implemented in any language, you just have to do it. This is nothing for the general Pascal file API however.

440bx

  • Hero Member
  • *****
  • Posts: 3946
As both @Bart and @loaded have already, implicitly or explicitly mentioned, the main problem is the performance of such a function.  For small files, a few kilobytes, it will usually be fine but, as files get larger the performance degradation will be substantial (the algorithm is O(n).)

There is also the ambiguity problem @Bart mentioned which can be very undesirable.

If you need direct access - by line number - multiple times then, scan the file once creating an index of where each line starts.  That way only one operation is O(n) (the scan), then each line access is O(1).

Also, the procedure/function that returns the line should include a mechanism to indicate to the caller that there is no line "n" to distinguish a non-existent line from an empty line.

IOW, heed @PascalDragon's advice :)

HTH.
 

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018