2009-03-16 30 views
6

Tôi có một số mã python rằng:Viết một đệm nhị phân vào một tập tin trong python

  1. Mất một BLOB từ một cơ sở dữ liệu đã được nén.
  2. Gọi một thường trình không nén trong C giải nén dữ liệu.
  3. Ghi dữ liệu chưa nén vào tệp.

Sử dụng ctypes để gọi thường trình C, trong thư viện được chia sẻ.

Điều này chủ yếu hoạt động, ngoại trừ việc ghi thực tế vào tệp. Để giải nén, tôi nhận được dữ liệu không nén vào một bộ đệm python, tạo ra bằng cách sử dụng ctypes create_string_buffer phương pháp:

c_uncompData_p = create_string_buffer(64000)

nên gọi uncompression là như thế này:

c_uncompSize = mylib.explodeCharBuffer (c_data_p, c_data_len, c_uncompData_p)

Kích thước của kết quả dữ liệu không nén được trả về dưới dạng giá trị trả lại.

Nhưng ... Tôi không có ý tưởng làm thế nào để buộc python trên chỉ viết c_uncompSize byte ra - nếu tôi làm:

myfile.write (c_uncompData_p.raw)

nó viết toàn bộ 64k đệm ra (các dữ liệu nhị phân là - vì vậy nó không phải là null chấm dứt).

Vì vậy, câu hỏi của tôi là - bằng cách sử dụng Python 2,5 làm thế nào để tôi nhận được c_uncompSize byte in ra, chứ không phải là toàn bộ 64k?

Cảm ơn Jamie

Trả lời

6

Cắt lát làm việc cho c_char_Arrays quá:

myfile.write(c_uncompData_p[:c_uncompSize]) 
+0

tác phẩm cắt lát nhưng tôi nghi ngờ rằng nó tạo ra một bản sao của dữ liệu. Nó có thể hoặc có thể không quan trọng (64K là một con số tương đối nhỏ). – jfs

+0

Cắt lát làm việc tốt và chạy tốt. Cảm ơn! –

+0

Có thể sử dụng 'itertools.islice()' để tránh tạo bản sao dữ liệu, – martineau

5

buffer() có thể giúp đỡ để tránh sao chép không cần thiết (do cắt như trong @elo80ka's answer):

myfile.write(buffer(c_uncompData_p.raw, 0, c_uncompSize)) 

Trong ví dụ của bạn nó không quan trọng (do c_uncompData_p chỉ được viết một lần và nó là nhỏ) nhưng nói chung nó có thể có ích.


Chỉ vì lợi ích của tập thể dục ở đây là câu trả lời có sử dụng C stdio 's fwrite():

from ctypes import * 

# load C library 
try: libc = cdll.msvcrt # Windows 
except AttributeError: 
    libc = CDLL("libc.so.6") # Linux 

# fopen() 
libc.fopen.restype = c_void_p 
def errcheck(res, func, args): 
    if not res: raise IOError 
    return res 
libc.fopen.errcheck = errcheck 
# errcheck() could be similarly defined for `fwrite`, `fclose` 

# write data 
file_p = libc.fopen("output.bin", "wb") 
sizeof_item = 1 # bytes 
nitems = libc.fwrite(c_uncompData_p, sizeof_item, c_uncompSize, file_p) 
retcode = libc.fclose(file_p) 
if nitems != c_uncompSize: # not all data were written 
    pass 
if retcode != 0: # the file was NOT successfully closed 
    pass 
+0

Cảm ơn câu trả lời của bạn. Cả hai phương pháp cắt và phương pháp đệm đều chạy với cùng tốc độ cho mục đích của tôi và cả hai đều hoạt động tốt theo chức năng. –

Các vấn đề liên quan