压缩写入Python3中的StringIO缓冲区的CSV文件

时间:2018-08-06 23:48:41

标签: python-3.x csv gzip

我正在将pdf文件中的文本解析为有序的char元数据行;我需要将这些文件序列化到云存储,一切正常,但是由于它们的大小,我也想对这些文件进行gzip压缩,但是我在其中遇到了一些问题。

这是我的代码:

import io
import csv
import zlib

# This data file is sent over Flask
page_position_data = pdf_parse_page_layouts(data_file)
field_order = ['char', 'position', 'page']

output_buffer = io.StringIO()
writer = csv.DictWriter(output_buffer, field_order)
writer.writeheader()
for page, rows in page_position_data.items():
    for text_char_data_row in rows:
        writer.writerow(text_char_data_row)

stored_format = zlib.compress(output_buffer)

这成功地将每一行读取到io.StringIO缓冲区中,但是gzip / zlib似乎只能与io.BytesIO之类的字节对象一起使用,因此最后一行会出错;我无法创建将CSV读取到BytesIO缓冲区中,因为除非使用io.StringIO(),否则DictWriter / Writer错误。

谢谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我发现了这个问题,想向遇到此问题的任何人展示我的答案:

问题在于zlib.compress期待一个类似Bytes的对象;这实际上并不意味着StringIO或BytesIO,因为它们都是“类文件”对象,它们实现了read()和常规的Unix文件句柄。

解决此问题所需要做的就是使用StringIO()将csv文件写入其中,然后从StringIO()对象调用get字符串并将其编码为字节字符串;然后可以通过zlib对其进行压缩。

import io
import csv
import zlib

# This data file is sent over Flask
page_position_data = pdf_parse_page_layouts(data_file)
field_order = ['char', 'position', 'page']

output_buffer = io.StringIO()
writer = csv.DictWriter(output_buffer, field_order)
writer.writeheader()
for page, rows in page_position_data.items():
    for text_char_data_row in rows:
        writer.writerow(text_char_data_row)

encoded = output_buffer.getvalue().encode()
stored_format = zlib.compress(encoded)

答案 1 :(得分:0)

对于有兴趣的人,应该使用较少的中间空间,我需要一个替代答案,它需要python 3.3及以上版本才能使用SELECT T2.ID, T1.ID FROM ( SELECT MIN(ID) AS ID, GroupNr FROM ( SELECT ID, ( Row_number()OVER(ORDER BY ID) - 1 ) / 3 + 1 AS GroupNr FROM Table ) AS T1 GROUP BY GroupNr ) AS T1 INNER JOIN ( SELECT ID, ( Row_number()OVER(ORDER BY ID) - 1 ) / 3 + 1 AS GroupNr FROM Table ) T2 ON T1.GroupNr = T2.GroupNr 方法:

getbuffer()