簡體   English   中英

處理文件時內存錯誤Python

[英]Memory Error Python When Processing Files

我有一個備份硬盤驅動器,我知道有重復的文件分散在我周圍,我認為這是一個有趣的項目,寫一個小的python腳本來找到它們並刪除它們。 我編寫以下代碼只是為了遍歷驅動器並計算每個文件的md5總和,並將其與我將稱之為“第一次遇到”列表的內容進行比較。 如果md5總和尚不存在,則將其添加到列表中。 如果總和已存在,則刪除當前文件。

import sys
import os
import hashlib

def checkFile(fileHashMap, file):
    fReader = open(file)
    fileData = fReader.read();
    fReader.close()
    fileHash = hashlib.md5(fileData).hexdigest()
    del fileData

    if fileHash in fileHashMap:
        ### Duplicate file.
        fileHashMap[fileHash].append(file)
        return True
    else:
        fileHashMap[fileHash] = [file]
        return False


def main(argv):
    fileHashMap = {}
    fileCount = 0
    for curDir, subDirs, files in os.walk(argv[1]):
        print(curDir)
        for file in files:
            fileCount += 1
            print("------------: " + str(fileCount))
            print(curDir + file)
            checkFile(fileHashMap, curDir + file)

if __name__ == "__main__":
    main(sys.argv)

該腳本處理大約10Gb的文件,然后在'fileData = fReader.read()'行上拋出MemoryError。 我認為,因為我在關閉fReader並在計算md5總和后將fileData標記為刪除,所以我不會遇到這個問題。 如何在不遇到此內存錯誤的情況下計算md5總和?

編輯:我被要求刪除字典並查看內存使用情況,以查看hashlib中是否存在泄漏。 這是我運行的代碼。

import sys
import os
import hashlib

def checkFile(file):
    fReader = open(file)
    fileData = fReader.read();
    fReader.close()
    fileHash = hashlib.md5(fileData).hexdigest()
    del fileData

def main(argv):
    for curDir, subDirs, files in os.walk(argv[1]):
        print(curDir)
        for file in files:
            print("------: " + str(curDir + file))
            checkFile(curDir + file)

if __name__ == "__main__":
    main(sys.argv)

我仍然得到內存崩潰。

你的問題在於讀取整個文件,它們太大而你的系統無法將它全部加載到內存中,因此它會拋出錯誤。

正如您在官方Python文檔中看到的, MemoryError是:

當操作耗盡內存時引發但情況仍可能被挽救(通過刪除一些對象)。 關聯值是一個字符串,表示內存中耗盡了哪種(內部)操作。 請注意,由於底層內存管理體系結構(C的malloc()函數), 解釋器可能無法始終從這種情況中完全恢復 ; 然而,它會引發異常,以便可以打印堆棧回溯,以防出現失控程序。

為了您的目的,您可以使用hashlib.md5()

在這種情況下,您必須按順序讀取4096字節的塊並將它們提供給Md5函數:

def md5(fname):
    hash = hashlib.md5()
    with open(fname) as f:
        for chunk in iter(lambda: f.read(4096), ""):
            hash.update(chunk)
    return hash.hexdigest()

不是您的內存問題的解決方案,而是可以避免它的優化:

  • 小文件:計算md5總和,刪除重復項

  • 大文件:記住大小和路徑

  • 最后,當有多個文件時,只計算相同大小的文件的md5sums

Python的collection.defaultdict可能對此有用。

如何從python中調用openssl命令在Windows和Linux中

$ openssl md5“文件”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM