我想從python中的二進制文件中修剪相同值的長序列。一個簡單的方法是簡單地讀取文件並使用re.sub替換不需要的序列。這當然不適用於大的二進制文件。它可以做像numpy的東西嗎?使用python從大型二進制文件中刪除字符序列
回答
如果你沒有內存做open("big.file").read()
,那麼numpy不會真的幫助..它使用與python變量相同的內存(如果你有1GB的RAM,你只能將1GB的數據加載到numpy中)
解決方法很簡單 - 以大塊讀取文件.. f = open("big.file", "rb")
,然後執行一系列f.read(500)
,刪除序列並將其寫回到另一個文件對象。幾乎你怎麼辦文件中讀取/編寫C ..
問題則是,如果你想你的更換模式。例如:
target_seq = "567"
input_file = "1234567890"
target_seq.read(5) # reads 12345, doesn't contain 567
target_seq.read(5) # reads 67890, doesn't contain 567
顯而易見的解決方案是在第一次啓動字符在文件中,檢查len(target_seq)
個字符,然後前進一個字符,再次檢查。
例如(僞代碼!):
while cur_data != "":
seek_start = 0
chunk_size = len(target_seq)
input_file.seek(offset = seek_start, whence = 1) #whence=1 means seek from start of file (0 + offset)
cur_data = input_file.read(chunk_size) # reads 123
if target_seq == cur_data:
# Found it!
out_file.write("replacement_string")
else:
# not it, shove it in the new file
out_file.write(cur_data)
seek_start += 1
這不正是最有效的方式,但它會工作,並且不需要保留文件的副本存儲在存儲器(或兩個)。
如果兩個副本適合內存,那麼您可以輕鬆地進行復制。第二個副本是壓縮版本。當然,你可以使用numpy,但你也可以使用array包。另外,你可以將你的大的二進制對象當作一串字節來處理,並直接對其進行處理。
聽起來像你的文件可能是真的是大,你不能適應兩個副本到內存中。 (你沒有提供很多細節,所以這只是一個猜測。)你必須做大塊壓縮。你會讀一塊,在這個塊上做一些處理並寫出來。再次,numpy,數組或簡單的字節串將可以正常工作。
你需要讓你的問題更加精確。你知道你想提前修剪的價值嗎?
假設你做什麼,我可能會搜索使用subprocess
運行「fgrep -o -b <search string>
」,然後更改使用Python file
對象的seek
,read
和write
方法文件的有關章節的匹配部分。
dbr的解決方案是一個好主意,但有點過於複雜,你必須做的是在你讀下一個塊之前,將文件指針倒回到你正在搜索的序列的長度。
def ReplaceSequence(inFilename, outFilename, oldSeq, newSeq):
inputFile = open(inFilename, "rb")
outputFile = open(outFilename, "wb")
data = ""
chunk = 1024
while 1:
data = inputFile.read(chunk)
data = data.replace(oldSeq, newSeq)
outputFile.write(data)
inputFile.seek(-len(oldSequence), 1)
outputFile.seek(-len(oldSequence), 1)
if len(data) < chunk:
break
inputFile.close()
outputFile.close()
這個基於生成器的版本一次只能保存文件內容的一個字符。
請注意,我正在逐字提取您的問題標題 - 您想將同一個字符的運行縮減爲單個字符。對於一般的更換圖案,這不起作用:
import StringIO
def gen_chars(stream):
while True:
ch = stream.read(1)
if ch:
yield ch
else:
break
def gen_unique_chars(stream):
lastchar = ''
for char in gen_chars(stream):
if char != lastchar:
yield char
lastchar=char
def remove_seq(infile, outfile):
for ch in gen_unique_chars(infile):
outfile.write(ch)
# Represents a file open for reading
infile = StringIO.StringIO("1122233333444555")
# Represents a file open for writing
outfile = StringIO.StringIO()
# Will print "12345"
remove_seq(infile, outfile)
outfile.seek(0)
print outfile.read()
AJMayorga建議是好的,除非替換字符串的大小是不同的。或者替換字符串位於塊的末尾。
我固定它是這樣的:
def ReplaceSequence(inFilename, outFilename, oldSeq, newSeq):
inputFile = open(inFilename, "rb")
outputFile = open(outFilename, "wb")
data = ""
chunk = 1024
oldSeqLen = len(oldSeq)
while 1:
data = inputFile.read(chunk)
dataSize = len(data)
seekLen= dataSize - data.rfind(oldSeq) - oldSeqLen
if seekLen > oldSeqLen:
seekLen = oldSeqLen
data = data.replace(oldSeq, newSeq)
outputFile.write(data)
inputFile.seek(-seekLen, 1)
outputFile.seek(-seekLen, 1)
if dataSize < chunk:
break
inputFile.close()
outputFile.close()
- 1. 從文本文件中刪除二進制控制字符
- 2. 從二進制文件中刪除字符
- 3. 如何從二進制文件中刪除前n個字符
- 4. 從二進制文件中刪除
- 5. C#如何從二進制文件中刪除換行符?
- 6. 從二進制文件中刪除字節
- 7. 使用removePIE刪除應用程序二進制文件的ALSR
- 8. 從Python中的二進制文件中提取字符串
- 9. 從文件中刪除控制字符
- 10. 使用python從二進制文件中讀取數字數據
- 11. Python - 從二進制文件中讀取字符串
- 12. 從字符串到二進制文件
- 13. 從文本文件中刪除ASCII控制字符Python
- 14. 如何從編譯的二進制文件中刪除字符串(.so)
- 15. 使用php刪除xml文件中的十六進制字符
- 16. 從大型二進制文件中提取zip文件
- 17. 使用Java搜索二進制文件中的字節序列
- 18. 從二進制最大堆中刪除第二小元素
- 19. 從字符串中刪除二進制零
- 20. 如何從字符串中刪除二進制內容?
- 21. Python:使用熊貓從CSV文件中刪除非ASCII字符
- 22. 使用python從文件中刪除非ASCII字符
- 23. 如何使用Python從txt文件中刪除特殊字符
- 24. 如何從ELF二進制文件中刪除程序頭文件
- 25. 刪除二進制Java文件
- 26. 在Python中閱讀大型二進制文件的部分
- 27. Python讀取二進制文件中的二進制數據到字符串?
- 28. 從文件第二列中刪除0.0
- 29. python從列表項中刪除字符
- 30. 大型二進制字符串的Python按位操作
謝謝,這有很大幫助。我希望numpy會對大文件進行一些自動內存管理 - 我對它不太熟悉。 – bluegray 2008-10-24 12:00:08