Python根据偏移量写入文件

时间:2011-12-12 17:47:34

标签: python

我想创建一个python程序,将文件拆分为指定宽度的段,然后使用者程序获取段并创建原始文件的副本。这些段可能出现故障,所以我打算使用偏移值写入文件。 有没有一种方法可以实现这一点,而无需创建一个本地数组来保存接收端的所有数据?

例如,

f = open(file, "wb")
f.seek(offset)
f.write(data)

这背后的想法是发送文件的程序可能无法完成发送文件,并且一旦启动就会再次恢复。 我有一个示例代码,当我尝试将数据放在缓冲区位置时,“combine_bytes”函数会抛出异常。

import sys
import os

def SplitFile(fname, start, end, width):
    t_fileSize = os.path.getsize(fname)
    buffData = bytearray(t_fileSize)
    for line, offset in get_bytes(fname, int(start), int(end), int(width)): 
    combine_bytes(buffData, offset, line, width)        
        nums = ["%02x" % ord(c) for c in line]
        print " ".join(nums)

    f = open("Green_copy.jpg", "wb")
    f.write(buffData)
    f.close()


def combine_bytes(in_buff, in_offset, in_data, in_width):
    #something like memcpy would be nice
    #in_buff[in_offset:in_offset + in_width] = in_data

    #this works but it's the mother of inefficiency 
    i = in_offset
    for c in in_data:
        in_buff.insert(i, c)
        i  = i + 1


def get_bytes(fname, start, end, width):
    t_currOffset = start
    t_width = width
    f = open(fname, "r+b")

    if end != 0:
    while t_currOffset < end:
        f.seek(t_currOffset)
        if (t_currOffset + t_width) > end:
            t_width = end - t_currOffset
        t_data = f.read(t_width)
        yield t_data,t_currOffset
        t_currOffset += t_width
    else:   
    f.seek(t_currOffset)
    t_data = f.read(t_width)
    while t_data:
        yield t_data, t_currOffset
        t_currOffset += t_width
        f.seek(t_currOffset)
        t_data = f.read(t_width)

    f.close()


if __name__ == '__main__':
    try:
    SplitFile(*sys.argv[1:5])
    except:
    print "Unexpected error:", sys.exc_info()[0]

2 个答案:

答案 0 :(得分:1)

我仍然无法弄清楚你的意图是什么 - 但这个版本的combine_bytes将摆脱你的“效率低下的母亲”部分(实际上就是这样)

def combine_bytes(in_buff, in_offset, in_data, in_width):
    #something like memcpy would be nice
    #in_buff[in_offset:in_offset + in_width] = in_data

    in_buff = in_buff[:in_offset] + in_data + in_buff[in_offset:] 
    return in_buff

当然这会为每个调用创建一个新的(更大的)缓冲区,并且必须将调用者作用域上的缓冲区替换为返回的缓冲区:

buffData = combine_bytes(buffData, offset, line, width)

答案 1 :(得分:0)

找到它。这是一种更好的方式,可以产生我想要的东西并且速度更快。 _buffData[t_offset:t_offset + len(t_data)] = bytearray(t_data)