2011-12-12 108 views
0

我想創建一個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] 
+0

讓您爲添加更多信息而添加。現在,您的代碼中存在幾個縮進錯誤,這些錯誤使其難以理解或測試。 (像第一個'for'內的combine_bytes調用 - 它應該縮進另一個層次) – jsbueno

回答

0

找到了。這是一種更好的方式,可以產生我想要的和更快的。 _buffData[t_offset:t_offset + len(t_data)] = bytearray(t_data)

1

我仍然NT弄清楚什麼是你的意圖 - 不過這個版本的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)

+0

對不起,我以爲我很清楚。哪一部分不清楚?而你的代碼做了竅門謝謝! – ArmenB

+0

其實,當我洗牌的時候,這段代碼的順序也是錯誤的。 '代碼''代碼' – ArmenB

+0

找到它。這是一種更好的方式,可以產生我想要的和更快的。 '_buffData [t_offset:t_offset + len(t_data)] = bytearray(t_data)' – ArmenB