reading files with error

Christian Stapfer nil at dev.nul
Sun Sep 18 06:51:09 CEST 2005


Maurice Ling <mauriceling at acm.org> wrote in message 
news:mailman.547.1127016906.509.python-list at python.org...
> jepler at unpythonic.net wrote:
>
>>I have written a program to do something similar.  My strategy is:
>> * use os.read() to read 512 bytes at a time
>> * when os.read fails, seek to the next multiple of 512 bytes
>>   and write '\0' * 512 to the output
>>I notice this code doesn't deal properly with short reads, but in my 
>>experience
>>they never happen (because the disk error makes an entire block 
>>unreadable, and
>>a block is never less than 512 bytes)
>>
>>I use this code on a unix-style system.
>>
>>def dd(src, target, bs=512):
>>    src = os.open(src, os.O_RDONLY)
>>    if os.path.exists(target):
>>        target = os.open(target, os.O_WRONLY | os.O_APPEND, 0600)
>>        existing = os.lseek(target, 0, SEEK_END)
>>    else:
>>        existing = 0
>>        target = os.open(target, os.O_WRONLY | os.O_CREAT, 0600)
>>
>>    total = os.lseek(src, 0, SEEK_END) / bs
>>    os.lseek(src, existing, SEEK_SET)
>>    os.lseek(target, existing, SEEK_SET)
>>
>>    if existing: print "starting at", existing
>>    i = existing / bs
>>    f = 0
>>    lastrem = -1
>>
>>    last = start = time.time()
>>    while 1:
>>        try:
>>            block = os.read(src, bs)
>>        except os.error, detail:
>>            if detail.errno == errno.EIO:
>>                block = "\0" * bs
>>                os.lseek(src, (i+1) * bs, SEEK_SET)
>>                f = f + 1
>>            else:
>>                raise
>>        if block == "": break
>>
>>        i = i + 1
>>        os.write(target, block)
>>
>>        now = time.time()
>>        if i % 1000 or now - last < 1: continue
>>        last = now
>>
>>        frac = i * 1. / total
>>        rem = int((now-start) * (1-frac) / frac)
>>        if rem < 60 or abs(rem - lastrem) > .5:
>>            rm, rs = divmod(rem, 60)
>>            lastrem = rem
>>        spd = i * 512. / (now - start) / 1024 / 1024
>>        sys.stderr.write("%8d %8d %8d %3.1f%% %6d:%02d %6.1fMB/s\r"
>>                        % (i, f, i-f, i * 100. / total, rm, rs, spd))
>>    sys.stderr.write("\n")
>>
>>
> Sorry but what are SEEK_END and SEEK_SET?

The Python 2.3 documentation seems to specify the *numeric*
values of these constants only. But since Python's file
objects are "implemented using C's stdio package", you
can read

http://www.opengroup.org/onlinepubs/009695399/functions/lseek.html

Regards,
Christian Stapfer





More information about the Python-list mailing list