Reputation: 21
This is my code for getting 20 lines every time but f1.tell() gives last position of the file. So i cannot get 20 lines for the next time. Can anyone help me to do this? please
f1=open("sample.txt","r")
last_pos=0
while true:
f1.seek(last_pos)
for line,i in enumerate(f1.readlines()):
if line == 20:
last_pos=f1.tell()
break
else:
print i
sample.txt file contains below data
1
2
3
4
.
.
.
.
40
I want Output like
1
2
3
4
.
.
.
20
20
21
22
23
24
25
.
.
.
.
39
39
40
Upvotes: 0
Views: 146
Reputation: 140287
Using readlines
reads all the file: you reach the end, hence what you are experiencing.
Using a loop with readline
works, though, and gives you the position of the end of the 20th line (well, rather the start of the 21st)
Code (I removed the infinite loop BTW):
f1=open("sample.txt","r")
last_pos=0
line=0
while True:
l=f1.readline()
if l=="":
break
line+=1
if line == 20:
last_pos=f1.tell()
print(last_pos)
break
f1.close()
You could iterate with for i,l in enumerate(f1):
but iterators & ftell are not compatible (you get: OSError: telling position disabled by next() call
).
Then, to seek to a given position, just f1.seek(last_pos)
EDIT: if you need to print the line twice eveny 20 lines, you actually don't even need seek
, just print the last line when you count 20 lines.
BUT if you really want to do that this way, here's the way:
f1=open("sample.txt","r")
line=0
rew=False
while True:
start_line_pos=f1.tell()
l=f1.readline()
if l=="":
break
print(l.strip())
line+=1
if rew:
rew = False # avoid re-printing the 20th line again and again
elif line % 20 == 0:
f1.seek(start_line_pos)
rew = True
line-=1 # pre-correct line counter
f1.close()
You notice a bit of logic to avoid getting stuck on line 20. It works fine: when reaching line 20, 40, ... it seeks back to the previously stored file position and reads 1 line again. The rew
flag prevents to do that more than once.
Upvotes: 1
Reputation: 149175
Jean-François Fabre already explained that readline
could read the whole file.
But anyway you should never mix line level input (readline
) and byte level input (tell
, seek
or read
). As the low level OS system calls can only read a byte count, readline
actually reads a buffer and searches for a newline in it. But the file pointer given by tell
is positionned at the end of the buffer and not at the end of the line.
There is no way to set the file pointer at the end of a line except by processing the file one char at a time and manually detecting the end of line.
Upvotes: 0