Python: التراجع عن تشغيل ملف readline () لذا عاد ملف الملف إلى الحالة الأصلية

StackOverflow https://stackoverflow.com/questions/3505479

سؤال

أنا أتصفح مؤشر ملف Python لملف نصي في وضع القراءة فقط باستخدام file.readline () يبحث عن سطر خاص. بمجرد أن أجد هذا السطر ، أريد تمرير مؤشر الملف إلى طريقة تتوقع أن يكون مؤشر الملف في بداية هذا الخط القراءة (ليس بعده مباشرة).

كيف يمكنني التراجع بشكل أساسي عن تشغيل ملف واحد. ReadLine () على مؤشر الملف؟

هل كانت مفيدة؟

المحلول

عليك أن تتذكر الموقف عن طريق الاتصال file.tell() قبل خط القراءة ثم الاتصال file.seek() لإرجاع. شيء مثل:

fp = open('myfile')
last_pos = fp.tell()
line = fp.readline()
while line != '':
  if line == 'SPECIAL':
    fp.seek(last_pos)
    other_function(fp)
    break
  last_pos = fp.tell()
  line = fp.readline()

لا أستطيع أن أتذكر ما إذا كان من الآمن الاتصال file.seek() داخل أ for line in file حلقة لذلك عادة ما أكتب while عقدة. ربما هناك طريقة أكثر إثارة للقيام بذلك.

نصائح أخرى

تقوم بتسجيل نقطة انطلاق الخط مع thefile.tell() قبل الاتصال readline, ، والعودة إلى هذه النقطة ، إذا كنت بحاجة ، مع thefile.seek.

>>> with open('bah.txt', 'w') as f:
...   f.writelines('Hello %s\n' % i for i in range(5))
... 
>>> with open('bah.txt') as f:
...   f.readline()
...   x = f.tell()
...   f.readline()
...   f.seek(x)
...   f.readline()
... 
'Hello 0\n'
'Hello 1\n'
'Hello 1\n'
>>> 

كما ترى ، فإن Seek/Tell "الزوج" هو "التراجع" ، إذا جاز التعبير ، فإن حركة مؤشر الملفات التي تؤديها readline. بالطبع ، لا يمكن أن يعمل هذا إلا على ملف فعلي يمكن البحث عنه (أي ، القرص) ، وليس (على سبيل المثال) على الكائنات الشبيهة بالملف المصنفة مع طريقة Makefile للمآخذ ، إلخ ، إلخ.

إذا كانت طريقتك تريد ببساطة التكرار من خلال الملف ، فيمكنك استخدامها itertools.chain لجعل التكرار المناسب:

import itertools

def process(it):
    for line in it:
        print line,

with open(filename,'r') as f:
    for line in f:
        if 'marker' in line:
            it=itertools.chain((line,),f)
            process(it)
            break
fin = open('myfile')
for l in fin:
    if l == 'myspecialline':
        # Move the pointer back to the beginning of this line
        fin.seek(fin.tell() - len(l))
        break
# now fin points to the start of your special line

إذا كنت لا تعرف السطر الأخير لأنك لم تزوره ، فيمكنك القراءة للخلف حتى ترى حرفًا جديدًا:

with open(logfile, 'r') as f:
    # go to EOF
    f.seek(0, os.SEEK_END)
    nlines = f.tell()
    i=0
    while True:
        f.seek(nlines-i)
        char = f.read(1)
        if char=='\n':
            break
        i+=1
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top