GZIP 最多字节限制,无需复制
GZIP Up To Byte Limit Without Copy
我想使用 gzip 将记录打包到 io.ByteIO 的列表中。我想为每个我不想超过的包设置一个 max_size。问题是我不知道在我这样做之前我是否会用新记录超过那个尺寸。一旦它超过了尺寸,我就没有好的方法来撤消该添加。
def pack_gz_records(records: List[any], max_size: int) -> List[io.BytesIO]:
packets = []
mem_file = io.BytesIO()
gz = gzip.GzipFile(fileobj=mem_file, mode="w")
for record in records:
if gz.size >= max_size:
# Size exceeded limit. Add this mem file to the package and cut a new mem file
mem_file.seek(0)
packets.append(mem_file)
mem_file = io.BytesIO()
gz = gzip.GzipFile(fileobj=mem_file, mode="w")
gz.write(serialize(record))
if gz.size:
mem_file.seek(0)
packets.append(mem_file)
return packets
有没有一种方法可以有效地撤消写入或“查看”写入,而无需在写入前复制每条记录的所有字节?
是的。使用 zlib
库(而不是 gzip
)。使用 wbits=31
到 select gzip 格式创建压缩对象。 copy()
函数可以在添加下一条记录之前复制压缩对象。复制后,将下一条记录添加到原始对象并用 Z_BLOCK
刷新。如果结果加上 gzip 尾部的一些余量,没有超过您的限制,则删除副本。如果确实过去了,则删除过去的对象,然后返回并完成(用 Z_FINISH
刷新)复制对象上的压缩。
这假设您的记录至少有几 K 大小,因此压缩不会受到刷新的显着影响。如果您的记录很小,您应该在刷新之前压缩几条记录。 (用每次刷新的记录数进行实验以衡量压缩影响。)如果你喜欢,当你超过限制并备份时,你可以通过二进制搜索来确定记录数填满就好了。
我想使用 gzip 将记录打包到 io.ByteIO 的列表中。我想为每个我不想超过的包设置一个 max_size。问题是我不知道在我这样做之前我是否会用新记录超过那个尺寸。一旦它超过了尺寸,我就没有好的方法来撤消该添加。
def pack_gz_records(records: List[any], max_size: int) -> List[io.BytesIO]:
packets = []
mem_file = io.BytesIO()
gz = gzip.GzipFile(fileobj=mem_file, mode="w")
for record in records:
if gz.size >= max_size:
# Size exceeded limit. Add this mem file to the package and cut a new mem file
mem_file.seek(0)
packets.append(mem_file)
mem_file = io.BytesIO()
gz = gzip.GzipFile(fileobj=mem_file, mode="w")
gz.write(serialize(record))
if gz.size:
mem_file.seek(0)
packets.append(mem_file)
return packets
有没有一种方法可以有效地撤消写入或“查看”写入,而无需在写入前复制每条记录的所有字节?
是的。使用 zlib
库(而不是 gzip
)。使用 wbits=31
到 select gzip 格式创建压缩对象。 copy()
函数可以在添加下一条记录之前复制压缩对象。复制后,将下一条记录添加到原始对象并用 Z_BLOCK
刷新。如果结果加上 gzip 尾部的一些余量,没有超过您的限制,则删除副本。如果确实过去了,则删除过去的对象,然后返回并完成(用 Z_FINISH
刷新)复制对象上的压缩。
这假设您的记录至少有几 K 大小,因此压缩不会受到刷新的显着影响。如果您的记录很小,您应该在刷新之前压缩几条记录。 (用每次刷新的记录数进行实验以衡量压缩影响。)如果你喜欢,当你超过限制并备份时,你可以通过二进制搜索来确定记录数填满就好了。