2024-06-14 20:02:04 发布
网友
我正在读取一个二进制文件(本例中是jpg),需要在该文件中找到一些值。对于那些感兴趣的人来说,二进制文件是一个jpg,我试图通过查找二进制结构detailed here来确定它的维数。
我需要在二进制数据中找到FFC0,跳过一些字节数,然后读取4个字节(这应该给我图像尺寸)。
在二进制数据中搜索值的好方法是什么?有没有类似于“发现”的东西,或者类似于re?
您可以使用mmap模块来完成这项工作,而不是将整个文件读入内存,搜索它,然后将新文件写入磁盘。mmap将而不是将整个文件存储在内存中,并允许就地修改。
#!/usr/bin/python import mmap with open("hugefile", "rw+b") as f: mm = mmap.mmap(f.fileno(), 0) print mm.find('\x00\x09\x03\x03')
bitstring模块就是为了这个目的而设计的。对于您的情况,下面的代码(我还没有测试过)应该有助于说明:
from bitstring import ConstBitStream # Can initialise from files, bytes, etc. s = ConstBitStream(filename='your_file') # Search to Start of Frame 0 code on byte boundary found = s.find('0xffc0', bytealigned=True) if found: print("Found start code at byte offset %d." % found[0]) s0f0, length, bitdepth, height, width = s.readlist('hex:16, uint:16, uint:8, 2*uint:16') print("Width %d, Height %d" % (width, height))
实际上,您可以将文件加载到字符串中,并使用str.find()方法搜索该字符串中的字节序列0xffc0。它适用于任何字节序列。
str.find()
0xffc0
执行此操作的代码取决于以下几点。如果以二进制模式打开文件,并且使用的是Python 3(这两种方法在本场景中可能都是最佳实践),则需要搜索字节字符串(而不是字符串),这意味着您必须在字符串前面加上b。
b
with open(filename, 'rb') as f: s = f.read() s.find(b'\xff\xc0')
如果在Python3中以文本模式打开文件,则必须搜索字符串:
with open(filename, 'r') as f: s = f.read() s.find('\xff\xc0')
尽管没有特别的理由这么做。与以前的方法相比,它没有任何优势,如果您所处的平台对二进制文件和文本文件的处理方式不同(例如,Windows),则有可能会导致问题。
Python 2没有区分字节字符串和字符串,因此如果您使用的是该版本,那么在b'\xff\xc0'中包含或排除b并不重要。如果您的平台对二进制文件和文本文件的处理方式相同(例如Mac或Linux),那么使用'r'或'rb'作为文件模式也无关紧要。但我还是建议您使用类似于上面第一个代码示例的方法来实现前向兼容性—如果您确实切换到Python3,那么就不需要修复它了。
b'\xff\xc0'
'r'
'rb'
您可以使用mmap模块来完成这项工作,而不是将整个文件读入内存,搜索它,然后将新文件写入磁盘。mmap将而不是将整个文件存储在内存中,并允许就地修改。
bitstring模块就是为了这个目的而设计的。对于您的情况,下面的代码(我还没有测试过)应该有助于说明:
实际上,您可以将文件加载到字符串中,并使用
str.find()
方法搜索该字符串中的字节序列0xffc0
。它适用于任何字节序列。执行此操作的代码取决于以下几点。如果以二进制模式打开文件,并且使用的是Python 3(这两种方法在本场景中可能都是最佳实践),则需要搜索字节字符串(而不是字符串),这意味着您必须在字符串前面加上
b
。如果在Python3中以文本模式打开文件,则必须搜索字符串:
尽管没有特别的理由这么做。与以前的方法相比,它没有任何优势,如果您所处的平台对二进制文件和文本文件的处理方式不同(例如,Windows),则有可能会导致问题。
Python 2没有区分字节字符串和字符串,因此如果您使用的是该版本,那么在
b'\xff\xc0'
中包含或排除b
并不重要。如果您的平台对二进制文件和文本文件的处理方式相同(例如Mac或Linux),那么使用'r'
或'rb'
作为文件模式也无关紧要。但我还是建议您使用类似于上面第一个代码示例的方法来实现前向兼容性—如果您确实切换到Python3,那么就不需要修复它了。相关问题 更多 >
编程相关推荐