python - 如何用单行拆分大文件?
问题描述
我有包含以下详细信息的输入文件:
文件大小:大约 3GB 到 5GB
行数:1(总是)
分隔符:_@%@_
文件类型:二进制
文件扩展名:txt
每个分隔符之间的数据大小:最大 5MB 每个分隔符之间
的数据长度:不可预测
可能有任何字符 [ _
, @
, %
] 介于两者之间:是
示例:
_@%@_4fdadfdcdfrffe3q_@%@_dfdsd8fs7dff9_@%@_jfdksadfdsfsdfjsalj_@%@_fsadklfjsdfewer0_@%@_dfsdfjsdlfdffdufdfudyfdf_@%@_
实际上,该文件包含用 . 分隔的多行_@%@_
。问题是没有换行符,因此我无法用_@%@_
我尝试分割线。但是得到MemoryError
(在线inputF.read()
)。
我想,如果我使用for line in open(inputFilePath):
, 会得到MemoryError
它自己,因为文件中只有一行(没有尝试过)。
inputF=open(inputFilePath, "r")
fullFile = inputF.read()
splitted = fullFile.split("_@%@_")
预期输出(阅读后,我必须将每一行转换为人类可读的格式)
shirt
form
some
human
readable
如果我尝试将其读取为块,如何正确拆分它以获得精确的行?
(比如说,我可能会得到_@%@_4fdadfdcdf
第一块和rffe3q_@%@_dfdsd8
第二块,对吧?)
更新:
将分隔符从 更改###
为_@%@_
。由于我不应该提供实际数据,我想只提供一个分隔符。没想过一个字一个字地读。
解决方案
解决方案 1
使用mmap
(修改其示例代码)和正则表达式:
import mmap, re
# write a simple example file
with open("hello.txt", "wb") as f:
f.write(b"_@%@_4fdadfdcdfrffe3q_@%@_dfdsd8fs7dff9_@%@_jfdksadfdsfsdfjsalj_@%@_fsadklfjsdfewer0_@%@_dfsdfjsdlfdffdufdfudyfdf_@%@_")
with open("hello.txt", "r+b") as f:
mm = mmap.mmap(f.fileno(), 0)
for match in re.finditer(b'(?<=_@%@_)(.*?)(?=_@%@_)', mm):
print(match[1])
输出(在线尝试!):
b'4fdadfdcdfrffe3q'
b'dfdsd8fs7dff9'
b'jfdksadfdsfsdfjsalj'
b'fsadklfjsdfewer0'
b'dfsdfjsdlfdffdufdfudyfdf'
没有将分隔符硬编码到模式中的版本(在线试用!):
delimiter = '_@%@_'
with open("hello.txt", "r+b") as f:
mm = mmap.mmap(f.fileno(), 0)
ed = re.escape(delimiter)
for match in re.finditer(f'(?<={ed})(.*?)(?={ed})'.encode(), mm):
print(match[1])
解决方案 2
或mmap
单独使用:
import mmap
# write a simple example file
with open("hello.txt", "wb") as f:
f.write(b"_@%@_4fdadfdcdfrffe3q_@%@_dfdsd8fs7dff9_@%@_jfdksadfdsfsdfjsalj_@%@_fsadklfjsdfewer0_@%@_dfsdfjsdlfdffdufdfudyfdf_@%@_")
delimiter = b'_@%@_'
with open("hello.txt", "r+b") as f:
mm = mmap.mmap(f.fileno(), 0)
start = mm.find(delimiter) + len(delimiter)
while (stop := mm.find(delimiter, start)) != -1:
print(mm[start:stop])
start = stop + len(delimiter)
输出:
b'4fdadfdcdfrffe3q'
b'dfdsd8fs7dff9'
b'jfdksadfdsfsdfjsalj'
b'fsadklfjsdfewer0'
b'dfsdfjsdlfdffdufdfudyfdf'
笔记
在所有情况下,如果您想要str
代替bytes
,请应用.decode()
到结果。
推荐阅读
- html - 缩小联系表格
- python - 在调用 deleteLater() 后直接删除对 Qt 对象的 Python 引用是否安全?
- vue.js - 在 Nuxt 中使用来自布局的异步获取
- spring - 将数据从 Soring 启动应用程序添加到 Mondo DB
- docker - 如何缩小 Docker 磁盘映像,但在 Docker for Mac 中保留卷?
- direct3d - 如何处理 Direct3D 9Ex D3DERR_DEVICEHUNG 错误?
- node.js - npm 错误的 .pem 文件!由于代理,无法在 Windows 中安装软件包
- arrays - 使用“MPI_Gatherv”沿第 n 维堆叠数组
- spring - 如果数据库在 Spring 5 和 Hibernate 中关闭,则 Autocrate 数据库忽略错误
- python - 在文件写入时创建目录树