2009-09-16 90 views
6

假設我們知道所有的文件都會被加載到內存中並且我們可以承受它, 在python中加載整個文件(可能是二進制文件)的缺點(如果有的話)或限制(如果有的話)有什麼缺點變量。如果這在技術上是可行的,是否應該避免,爲什麼?我們可以使用一個python變量來保存整個文件嗎?

關於文件大小的問題,該解決方案應該限制在什麼最大尺寸?爲什麼?

實際加載代碼可能是this stackoverflow entry中提出的代碼。

示例代碼:

def file_get_contents(filename): 
    with open(filename) as f: 
     return f.read() 

content = file_get_contents('/bin/kill') 

... code manipulating 'content' ... 

[編輯] 代碼操縱想到的(但也許是不適用)的標準列表/串運算符(方括號,「+」號)或一些字符串('len','in','count','endswith'/'startswith','split','translation'...)。

回答

6

雖然你已經得到了很好的迴應,似乎沒有人回答你的問題,這部分(如當你問一個問題,很多問題經常發生; - )...:

關於文件大小顧慮,什麼 最大規模這個解決方案應該是 有限?爲什麼?

最重要的事情是,有多少物理內存可這個具體的Python的過程實際上使用(什麼是所謂的「工作組」),而不會過度懲罰整個系統的性能的其他方面。如果您的「工作集」超出物理內存,您將分頁並交換到磁盤,並且您的性能可能會迅速降低(最高可達所謂的「抖動」狀態,基本上所有可用的週期都將轉到頁面進出的任務,以及可忽略的實際工作量實際上可以完成)。

在這個總數中,可能會被可執行代碼(Python自己的可執行文件,DLL或.so)以及字節碼和一般支持佔用合理適度的數量(通常是最多幾MB)內存中主動需要的數據結構;在一臺沒有做其他重要或緊急任務的典型現代機器上,與總體可用的千兆字節RAM相比,您幾乎可以忽略這種開銷(儘管嵌入式系統的情況可能不同)。

其餘所有內容都可用於您的數據 - 其中包括您正在讀入內存的此文件以及任何其他重要的數據結構。文件數據的「修改」通常會佔用文件內容大小兩倍的內存(如果將它保存在一個字符串中) - 當然,如果保留一份舊數據以及製作新的修改後的副本/版本。

因此,對於一個典型的現代32位機器,例如總體上具有2GB RAM的「只讀」應用,讀入內存(比如說)1.5 GB應該不成問題;但是如果你正在做「修改」(如果你在內存中有其他重要的數據結構,那麼它將少得多)。當然,在64位版本的Python,64位操作系統和16 GB RAM的專用服務器上,實際的限制在很大程度上不同 - 實際上與可用內存的數量大致成比例。

例如,King James的聖經文本可下載here(解壓縮)約爲4.4 MB;因此,在具有2 GB RAM的機器中,可以在內存中保留大約400個略微修改過的副本(如果沒有其他內存請求),但在具有16 GB(可用且可尋址)GB的機器中,您可以保存好3000多份這樣的副本。

11
  • 是的,你可以
  • 唯一的缺點就是內存使用情況,以及可能也加快如果該文件是大。
  • 文件大小應該限制在內存中有多少空間。

一般來說,有更好的方法來做到這一點,但對於一次性腳本,你知道內存不是問題,當然。

3

您可以遇到的唯一問題是內存消耗:Python中的字符串是不可變的。所以,當你需要改變一個字節,你需要複製老的字符串:

new = old[0:pos] + newByte + old[pos+1:] 

這需要高達old三倍的內存。您可以使用array而不是字符串。如果您需要修改內容並且可以通過字符串輕鬆創建它們,這些提供了更好的性能。

4
with open(filename) as f: 

這隻適用於Unix上的Python 2.x。它不會達到您對Python 3.x或Windows的期望,因爲它們都在文本和二進制文件之間形成了強烈的區別。這是更好地指定該文件是二進制的,就像這樣:

with open(filename, 'rb') as f: 

這將關閉操作系統的CR/LF轉換在Windows,並會迫使Python 3.x都有返回一個字節數組,而不是Unicode字符。

至於你的問題的其餘部分,我同意倫納特Regebro的(未經編輯的)答案。

0

是的,你可以-provided文件很小enough-。

甚至進一步將read()返回值轉換爲任何容器/可迭代類型(如string.split())以及相關的函數式編程功能以繼續處理「立即」文件甚至是非常pythonic。

1

您也可以使用Python的V3功能:

>>> ''.join(open('htdocs/config.php', 'r').readlines()) 
"This is the first line of the file.\nSecond line of the file" 

在這裏閱讀更多http://docs.python.org/py3k/tutorial/inputoutput.html

+1

看我其他的評論,垃圾郵件的舊文章重複的答案是沒有建設性。 – Kev 2012-06-07 21:56:04

相關問題