在python中将二进制缓冲区写入文件

时间:2009-03-16 23:30:36

标签: python binary io

我有一些python代码:

  1. 从压缩的数据库中获取BLOB。
  2. 在C中调用解压缩数据的非压缩例程。
  3. 将未压缩的数据写入文件。
  4. 它使用ctypes来调用C例程,该例程位于共享库中。

    除了实际写入文件之外,这大部分都有效。为了解压缩,我将未压缩的数据放入python缓冲区,使用ctypes create_string_buffer方法创建:

    c_uncompData_p = create_string_buffer(64000)

    所以解压缩调用是这样的:

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

    生成的未压缩数据的大小将作为返回值返回。

    但是......我不知道如何强制python只写c_uncompSize字节 - 如果我这样做:

    myfile.write (c_uncompData_p.raw)

    它将整个64k缓冲区写出来(数据是二进制的 - 因此它不会以空值终止)。

    所以,我的问题是 - 使用Python 2.5如何打印出c_uncompSize字节,而不是整个64k?

    由于 杰米

2 个答案:

答案 0 :(得分:6)

切片也适用于c_char_Arrays:

myfile.write(c_uncompData_p[:c_uncompSize])

答案 1 :(得分:6)

buffer()可能有助于避免不必要的复制(由@elo80ka's answer中的切片引起):

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

在你的例子中没关系(由于c_uncompData_p只写了一次而且很小),但一般来说它可能很有用。


仅仅为了练习,这里是使用C stdio 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