2017-10-14 247 views
1

我有一個文件夾,裏面裝滿了需要修改的文件,以便以真實格式提取真實文件。如何從Python文件的開頭和結尾刪除特定數量的字節?

我需要從文件的開頭和結尾刪除一定數量的字節,以便提取我正在查找的數據。

我如何在python中做到這一點?

  • 我需要這對整個文件夾遞歸工作僅
  • 我還需要此輸出(或修改等植物學)除去了字節的文件。

我將不勝感激任何幫助或指導,你可以提供。

+1

你嘗試過什麼到目前爲止,哪裏是代碼? +提供文件中的數據樣本,你的問題太寬了 – Yahya

+0

我不知道從哪裏開始在python中,我的文件目前只能在十六進制中看到。只要我從頭到尾(使用十六進制編輯器)刪除前4個字節和幾個字節,然後獲得我的gzip文件。 – JoeyD

+2

您可以輕鬆刪除文件末尾的字節,但不能從文件開頭(或中間)刪除字節。您需要將它們替換爲其他字節,或者讀取要保留的字節並將它們寫回原始文件或寫入新文件。 –

回答

1
  1. 在文件os.walk
  2. 中的文件更改位置遞歸迭代:f.seek
  3. 獲取文件大小:os.stat
  4. 從當前位置刪除數據文件結尾:f.truncate

所以,基本邏輯:

  1. 迭代文件
  2. 獲取文件大小。
  3. 打開文件( 'RB +' 我suppouse)
  4. 從要讀文件
  5. 看,直到你要刪除字節至極尋找到位置(f.read(FILE_SIZE - top_dropped - bottom_dropped))
  6. 求(0)
  7. 寫讀文本到文件
  8. 截斷文件
+0

好的,我會從這裏開始。非常感謝您輸入yuroslav! – JoeyD

0

你的問題是相當嚴重的構造,但因爲這是有點高級的東西,我會爲你提供一個代碼。

您現在可以使用os.walk()遞歸遍歷您想要的目錄並應用我的slicefile()函數。

此代碼執行以下操作:

  1. 檢查的開始和結束參數生效後它創建一個打開的文件的頂部的存儲器映射。 mmap()創建一個內存映射對象,在這種情況下映射文件系統的一部分,在該文件系統上寫入文件。該對象公開了類似字符串和類似文件的接口以及一些其他方法,如move()。因此,您可以將內存映射視爲字符串或文件,或使用size(),move(),resize()或任何其他您需要的方法。

  2. 我們計算出我們的開始和結束之間的距離,也就是說我們最終會得到多少字節。

  3. 我們將字節流從終點開始移動,從我們的起始位置開始到0位置,即我們將它們向後移動以獲得由起點指示的字節數。

  4. 我們丟棄文件的其餘部分。即我們將其大小調整爲結束開始字節。所以剩下的是我們的新弦。

由於文件較大,操作時間會更長。不幸的是,你無能爲力。如果文件很大,這是你最好的選擇。該過程與從內存數組的開始/中間刪除項目相同,除了必須緩衝(以塊爲單位)而不是過多地填充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() 

+0

這是蟒蛇2還是3? – JoeyD

+0

它是Python 2.5及更高版本。至於3.x,我沒有看到任何不兼容的東西,除非他們改變了mmap模塊。我沒有在這裏,所以我不能嘗試。這個代碼基本上是做Yaroslav Surzhikov描述的。 – Dalen

+0

謝謝戴琳。我非常感謝你的時間!我仍然無法理解這段代碼。也許我應該更好地解釋我的困境。我有一個文件夾,裏面有一大堆從手機磁盤中提取的文件。這些文件基本上都是垃圾文件,直到從開頭的前8個字節開始,最後12個字節被刪除。一旦發生這種情況,他們將成爲gzip文件,這些文件具有我需要的取證證據。我可以用一個十六進制編輯器手動執行此操作,但由於我至少有1000個文件,所以我確實需要腳本 – JoeyD

相關問題