开发者

problem with seek() in file handling

开发者 https://www.devze.com 2023-02-18 07:54 出处:网络
I am using seek in a file-the file has a bunch of filenames and some logs of a process done on the file- some of these logs have errors. I am going line by line, if i get an error, I want to log every

I am using seek in a file- the file has a bunch of filenames and some logs of a process done on the file- some of these logs have errors. I am going line by line, if i get an error, I want to log everything in between two filenames.

When I use seek, I think that instead of moving it t开发者_StackOverflow中文版o the line i want it to, it moves it to the character # instead. For example

f=open("fileblah",'r')
while f:
   line=f.readline()
   counter=counter+1
   f.seek(tail_position) # i want the next loop to start from after the error happened.

   if line.startswith("D:")
      header_position=counter
      error_flag=0 #unset error flag
   if line.startswith("error")
        error_flag=1       #set error_flag           
        while(not(line.startswith("D:"): #go until next file beginning
           line=f.readline()
           counter=counter+1
        tail_position=counter #have come to the next filename

I can see this is highly inefficient, but it doesn't work at all, because f.seek(tail_position) is moving the file pointer to the character # instead of the line #


Use .tell() to store your start-of-line position, then you can .seek() back to it.

Edit: I think this is what you want:

def errorsInLog(fname, newfileStr='D:', iserrorStr='error'):
    with open(fname) as inf:
        prev = pos = inf.tell()
        line = inf.readline()
        error = False

        while line:
            if line.startswith(newfileStr):
                if error:
                    inf.seek(prev)
                    yield(inf.read(pos-prev))
                prev = pos
                error = False
            elif line.startswith(iserrorStr):
                error = True

            pos = inf.tell()
            line = inf.readline()

        if error:
            inf.seek(prev)
            yield(inf.read())

def main():
    print('\n\n'.join(errorsInLog('fileblah')))

For each filename followed by an error it returns a string encompassing the filename and all following lines, up to but not including the next filename or end-of-file.


seek() is used more often in random access file reading. If the file being read is already text and in can be read line by line then you need only read the line and then operate on the line using string operations. There is no need to move the file read position.

Your code need only look like this:

for line in f:  
    do_stuff_with line


like stdio's fseek(),seek(offset[,whence]) sets offset of the current position. whence is defaults to 0.so you can do something like this:

while(not(line.startwith("D:"))):
      fseek(tail_position,'\n')
      tail_position ++
0

精彩评论

暂无评论...
验证码 换一张
取 消