在 Python 3.6 中提取没有 BOM 的 gzip 文件
Extract gzip file without BOM in Python 3.6
我在子文件夹中有多个 gz 文件,我想将它们解压缩到一个文件夹中。它工作正常,但在我想删除的每个文件的开头都有一个 BOM 签名。我已经检查了 Removing BOM from gzip'ed CSV in Python or Convert UTF-8 with BOM to UTF-8 with no BOM in Python 等其他问题,但它似乎不起作用。我在 Windows 上的 Pycharm 中使用 Python 3.6。
这是我未经尝试的第一个代码:
import gzip
import pickle
import glob
def save_object(obj, filename):
with open(filename, 'wb') as output: # Overwrites any existing file.
pickle.dump(obj, output, pickle.HIGHEST_PROTOCOL)
output_path = 'path_out'
i = 1
for filename in glob.iglob(
'path_in/**/*.gz', recursive=True):
print(filename)
with gzip.open(filename, 'rb') as f:
file_content = f.read()
new_file = output_path + "z" + str(i) + ".txt"
save_object(file_content, new_file)
f.close()
i += 1
现在,如果我将 file_content = f.read()
替换为 file_content = csv.reader(f.read().decode('utf-8-sig').encode('utf-8').splitlines())
,则根据 Removing BOM from gzip'ed CSV in Python 中定义的逻辑(至少我的理解是这样),我得到:
TypeError: can't pickle _csv.reader objects
我检查了这个错误(例如 "Can't pickle <type '_csv.reader'>" error when using multiprocessing on Windows),但我找不到可以应用的解决方案。
对您 link 提出的第一个问题进行了细微的改编。
tripleee$ cat bomgz.py
import gzip
from subprocess import run
with open('bom.txt', 'w') as handle:
handle.write('\ufeffmoo!\n')
run(['gzip', 'bom.txt'])
with gzip.open('bom.txt.gz', 'rb') as f:
file_content = f.read().decode('utf-8-sig')
with open('nobom.txt', 'w') as output:
output.write(file_content)
tripleee$ python3 bomgz.py
tripleee$ gzip -dc bom.txt.gz | xxd
00000000: efbb bf6d 6f6f 210a ...moo!.
tripleee$ xxd nobom.txt
00000000: 6d6f 6f21 0a moo!.
pickle
部分在这里似乎不相关,但可能掩盖了从 bytes
.[= 的编码 blob 中获取解码 str
块的目标。 14=]
我在子文件夹中有多个 gz 文件,我想将它们解压缩到一个文件夹中。它工作正常,但在我想删除的每个文件的开头都有一个 BOM 签名。我已经检查了 Removing BOM from gzip'ed CSV in Python or Convert UTF-8 with BOM to UTF-8 with no BOM in Python 等其他问题,但它似乎不起作用。我在 Windows 上的 Pycharm 中使用 Python 3.6。
这是我未经尝试的第一个代码:
import gzip
import pickle
import glob
def save_object(obj, filename):
with open(filename, 'wb') as output: # Overwrites any existing file.
pickle.dump(obj, output, pickle.HIGHEST_PROTOCOL)
output_path = 'path_out'
i = 1
for filename in glob.iglob(
'path_in/**/*.gz', recursive=True):
print(filename)
with gzip.open(filename, 'rb') as f:
file_content = f.read()
new_file = output_path + "z" + str(i) + ".txt"
save_object(file_content, new_file)
f.close()
i += 1
现在,如果我将 file_content = f.read()
替换为 file_content = csv.reader(f.read().decode('utf-8-sig').encode('utf-8').splitlines())
,则根据 Removing BOM from gzip'ed CSV in Python 中定义的逻辑(至少我的理解是这样),我得到:
TypeError: can't pickle _csv.reader objects
我检查了这个错误(例如 "Can't pickle <type '_csv.reader'>" error when using multiprocessing on Windows),但我找不到可以应用的解决方案。
对您 link 提出的第一个问题进行了细微的改编。
tripleee$ cat bomgz.py
import gzip
from subprocess import run
with open('bom.txt', 'w') as handle:
handle.write('\ufeffmoo!\n')
run(['gzip', 'bom.txt'])
with gzip.open('bom.txt.gz', 'rb') as f:
file_content = f.read().decode('utf-8-sig')
with open('nobom.txt', 'w') as output:
output.write(file_content)
tripleee$ python3 bomgz.py
tripleee$ gzip -dc bom.txt.gz | xxd
00000000: efbb bf6d 6f6f 210a ...moo!.
tripleee$ xxd nobom.txt
00000000: 6d6f 6f21 0a moo!.
pickle
部分在这里似乎不相关,但可能掩盖了从 bytes
.[= 的编码 blob 中获取解码 str
块的目标。 14=]