Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

FILESEEKL?

May
12,846
164
Does FILESEEKL accept a negative line number when moving relative to the current line? ... seems not.

set seek=%@fileseek[%handle,-10,1] always brings me to the first line of the file.
 
From its help: "@FILESEEKL must read each line of the file up to the target line in order to position the pointer, and can therefore cause significant delays if used in a loop or on a large file." This implies forward-only, since moving backwards would require to first determine the current line number, requiring reading the whole file a line at a time, from BOF to the current pointer position to obtain the current line number, calculating the line number of the desired new position, and reading again from BOF to the newly selected line.

A new method to deal with line-oriented files would be to build a hidden array of line pointers, one for every line for small files, one for every 16 or 64 ... lines, as the file is read (or even as the file is opened, or when the first line-mode access is made. or as each physical block is read), and using the array determine how to access a specific line (utilizing the API call underlying @fileseek[], NOT @FILESEEKL[]). The pointer array for every 16th line would be used analogously to the same manner of calculating trigonometric functions in precomputer days - interpolating between tabulated results.
 
Does @FILESEEKL relative to the current line work at all? Below, the file is ordered by IP range, and after I echo lines 10000 and 10001 and %@fileseekl[handle,1,1] I get the second line of the file! I was expecting line 10003.

Code:
v:\> set h=%@fileopen[IpToCountry.csv,r]
 
v:\> set seek=%@fileseekl[%h,10000]
 
v:\> echo %@fileread[%h]
1170456576,1170472959,US
 
v:\> echo %@fileread[%h]
1170472960,1170481151,CA
 
v:\> set seek=%@fileseekl[%h,1,1]
 
v:\> echo %@fileread[%h]
16777216,16777471,AU    <=== that's the second line of the file!

Oddly, if I try a similar experiment with a small file, it works OK:

Code:
v:\> set h=%@fileopen[abc.txt,r]
 
v:\> set seek=%@fileseekl[%h,3]
 
v:\> echo %@fileread[%h]
d
 
v:\> echo %@fileread[%h]
e
 
v:\> set seek=%@fileseekl[%h,1,1]
 
v:\> echo %@fileread[%h]
g
 
Here's a self-contained one:
Code:
v:\> do i=0 to 100000 ( echo %i >> 0-100000.txt )
 
v:\> set h=%@fileopen[0-100000.txt,r]
 
v:\> set seek=%@fileseekl[%h,50000]
 
v:\> echo %@fileread[%h]
50000
 
v:\> echo %@fileread[%h]
50001
 
v:\> set seek=%@fileseekl[%h,1,1]
 
v:\> echo %@fileread[%h]
1
 
This is one of the weirdest bugs I have seen. Below, the two 11-line files are the same except for the last line (one having "x", the other having "10"). Yet, they show different results after echoing line 5 and then (supposedly) incrementing the pointer by one line (expecting line 7).
Code:
v:\> do f in /l abc.txt seektest.txt ( type %f & echo. & set h=%@fileopen[%f,r]
& set seek=%@fileseekl[%h,5] & echo line 5: %@fileread[%h] & set seek=%@fileseekl[%h,1,1]
& echo line ?: %@fileread[%h] & echo. & set h=%@fileclose[%h] )
0
1
2
3
4
5
6
7
8
9
x
 
line 5: 5
line ?: 7
 
0
1
2
3
4
5
6
7
8
9
10
 
line 5: 5
line ?: 1

In another test of file sizes 4 to 4000 (where line N is the number N), a similar test gets it wrong for all but 3 sizes less than 100, for every second size between 100 and 1000, and for every size greater than 1000. As I said, very strange!
 
Fixed for the next build. (The Unicode check was skewing the file read position.)
Now that you say that, my later observations don't seem so mysterious. It seemed to work/not work depending on the parity of the file size (or something like that).
 
Back
Top