如何从Python文件的开头和结尾删除特定数量的字节?
我有一个文件夹,里面装满了需要修改的文件,以便以真实格式提取真实文件。如何从Python文件的开头和结尾删除特定数量的字节?
我需要从文件的开头和结尾删除一定数量的字节,以便提取我正在查找的数据。
我如何在python中做到这一点?
- 我需要这对整个文件夹递归工作仅
- 我还需要此输出(或修改等植物学)除去了字节的文件。
我将不胜感激任何帮助或指导,你可以提供。
- 在文件os.walk
- 中的文件更改位置递归迭代:f.seek
- 获取文件大小:os.stat
- 从当前位置删除数据文件结尾:f.truncate
所以,基本逻辑:
- 迭代文件
- 获取文件大小。
- 打开文件( 'RB +' 我suppouse)
- 从要读文件
- 看,直到你要删除字节至极寻找到位置(f.read(FILE_SIZE - top_dropped - bottom_dropped))
- 求(0)
- 写读文本到文件
- 截断文件
好的,我会从这里开始。非常感谢您输入yuroslav! – JoeyD
你的问题是相当严重的构造,但因为这是有点高级的东西,我会为你提供一个代码。
您现在可以使用os.walk()递归遍历您想要的目录并应用我的slicefile()函数。
此代码执行以下操作:
检查的开始和结束参数生效后它创建一个打开的文件的顶部的存储器映射。 mmap()创建一个内存映射对象,在这种情况下映射文件系统的一部分,在该文件系统上写入文件。该对象公开了类似字符串和类似文件的接口以及一些其他方法,如move()。因此,您可以将内存映射视为字符串或文件,或使用size(),move(),resize()或任何其他您需要的方法。
我们计算出我们的开始和结束之间的距离,也就是说我们最终会得到多少字节。
我们将字节流从终点开始移动,从我们的起始位置开始到0位置,即我们将它们向后移动以获得由起点指示的字节数。
我们丢弃文件的其余部分。即我们将其大小调整为结束开始字节。所以剩下的是我们的新弦。
由于文件较大,操作时间会更长。不幸的是,你无能为力。如果文件很大,这是你最好的选择。该过程与从内存数组的开始/中间删除项目相同,除了必须缓冲(以块为单位)而不是过多地填充RAM。如果你的文件小于你的空闲RAM空间的三分之一,你可以用f.read()把它全部加载到一个字符串中,然后在加载的内容上执行字符串切片(s = s [start:end] ),然后通过再次打开并写入f.write(s)将其重新写入文件。 如果您有足够的磁盘空间,您可以打开另一个文件,在原始文件中寻找您想要的起点,然后以块的形式读取它们,并将它们写入新文件。也许甚至使用shutil.copyfileobj()。之后,您将删除原始文件并使用os.rename()将新文件放置到位。这是你唯一的3个选择。 整个文件到RAM中;向后缓冲,然后调整大小;并复制到另一个文件中,然后重命名它。第二种选择是最普遍的,并且不会让小型或大型文件失败。所以我用它。
好的,不仅有3个选项。还有第四种选择。通过使用低级操作来操作文件系统本身,可以从文件的开始处截断N个字节。编写一种截断开始而不是结束的truncate()函数。但这将是非常自杀的。最后会发生内存碎片,并且会出现整个混乱。无论如何,你不需要这样的速度。你的耐心直到你的剧本结束。 :D
为什么我使用mmap()?
因为它使用在OS中实现的内存映射而不是全新的代码。这减少了处理打开的文件所需的系统调用的数量。一半的工作都集中在操作系统上,让Python轻松呼吸。
因为它主要是用C编写的,所以它比纯Python实现更快。
因为它实现了需要的move()。缓冲和一切都已经写好,所以没有需要大的while循环,这将是替代(手动)解决方案。
等等......
from mmap import mmap
def slicefile (path, start=0, end=None):
f = open(path, "r+b") # Read and write binary
f.seek(0, 2)
size = f.tell()
start = 0 if start==None else start
end = size if end==None else end
start = size+start if start<0 else start
end = size+end if end<0 else end
end = size if end>size else end
if (end==size and start==0) or (end<=start):
f.close()
return
# If start is 0, no need to move anything, just cut off the rest after end
if start==0:
f.seek(end)
f.truncate()
f.close()
return
# Modify in place using mapped memory:
newsize = end-start
m = mmap(f.fileno(), 0)
m.move(0, start, newsize)
m.flush()
m.resize(newsize)
m.close()
f.close()
这是蟒蛇2还是3? – JoeyD
它是Python 2.5及更高版本。至于3.x,我没有看到任何不兼容的东西,除非他们改变了mmap模块。我没有在这里,所以我不能尝试。这个代码基本上是做Yaroslav Surzhikov描述的。 – Dalen
谢谢戴琳。我非常感谢你的时间!我仍然无法理解这段代码。也许我应该更好地解释我的困境。我有一个文件夹,里面有一大堆从手机磁盘中提取的文件。这些文件基本上都是垃圾文件,直到从开头的前8个字节开始,最后12个字节被删除。一旦发生这种情况,他们将成为gzip文件,这些文件具有我需要的取证证据。我可以用一个十六进制编辑器手动执行此操作,但由于我至少有1000个文件,所以我确实需要脚本 – JoeyD
你尝试过什么到目前为止,哪里是代码? +提供文件中的数据样本,你的问题太宽了 – Yahya
我不知道从哪里开始在python中,我的文件目前只能在十六进制中看到。只要我从头到尾(使用十六进制编辑器)删除前4个字节和几个字节,然后获得我的gzip文件。 – JoeyD
您可以轻松删除文件末尾的字节,但不能从文件开头(或中间)删除字节。您需要将它们替换为其他字节,或者读取要保留的字节并将它们写回原始文件或写入新文件。 –