標籤:
#作用:建立記憶體對應檔而不是直接讀取內容
文本資訊內容:如下(名稱是text.txt)
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec
egestas, enim et consectetuer ullamcorper, lectus ligula rutrum leo,
a elementum elit tortor eu quam. Duis tincidunt nisi ut ante. Nulla
facilisi. Sed tristique eros eu libero. Pellentesque vel
arcu. Vivamus purus orci, iaculis ac, suscipit sit amet, pulvinar eu,
lacus. Praesent placerat tortor sed nisl. Nunc blandit diam egestas
dui. Pellentesque habitant morbi tristique senectus et netus et
malesuada fames ac turpis egestas. Aliquam viverra fringilla
leo. Nulla feugiat augue eleifend nulla. Vivamus mauris. Vivamus sed
mauris in nibh placerat egestas. Suspendisse potenti. Mauris
massa. Ut eget velit auctor tortor blandit sollicitudin. Suspendisse
imperdiet justo.
簡介
記憶體對應檔對象類似字串和類似檔案的對象。不同於通常的字串對象,它可以是可變的。在需要字串的時候可以使用mmap對象;例如使用re模組對記憶體對應檔進行進行搜尋。修改單個字元:obj[index] = ‘a‘,或通過切片更改字串:[i1:i2] = ‘...‘。可以讀寫入當前檔案位置資料,並 seek()定位到檔案的其他位置。
記憶體對應檔是由mmap的建構函式建立,在Unix和Windows有所不同。兩者都需要提供檔案描述符。如果要映射已開啟的Python檔案對象,需要使用fileno()。或者使用os.open()函數(返迴文件描述符,但是如需要手工關閉)開啟檔案。建立可寫的記憶體對應檔用於buffer,必須先flush()檔案以確保對buffer本地修改也對映射生效。
Unix和Windows版本的構造方法都可以指定選擇性參數access。選項:ACCESS_READ,ACCESS_WRITE,或ACCESS_COPY,分別表示讀,寫,拷貝訪問。Windows預設是寫,。初始記憶體值是由檔案指定,寫ACCESS_READ的對象將會baoc。分配到ACCESS_READ儲存空間映射引發TypeError異常。ACCESS_WRITE內會影響記憶體和底層檔案。ACCESS_COPY內影響記憶體,但不會更新底層檔案。
#注意:這些模組所有都是2.X版本的,3.X可能沒有這些模組
#注意:unix和windows下面的mmap()參數和行為是有所差別的,請看官方文檔,地址如下:https://docs.python.org/2/library/mmap.html
#讀取檔案
"""
使用mmap()函數可以建立一個內在對應檔,第一參數是檔案描述符,可以file對象的fileno()方法,或者來自os.open()
。調用都在調用mmap()之前負責開啟檔案,不再需要檔案時要負責關閉
第二參數是要對應檔部分的大小(以位元組為單位),這個值為0,則映射整個檔案,如果大小大於檔案當前大小,則會該檔案.
"""
#注意:windows下面不支援建立長度為0的映射
#此2平台都支援一個可選關鍵字參數access,ACCESS_READ,ACCESS_WRITE,或ACCESS_COPY,分別表示讀,寫,拷貝訪問。Windows預設是寫,
#對記憶體的賦值不會寫至檔案
import contextlib,mmap,re
with open(r‘text.txt‘,‘r‘)as f:
with contextlib.closing(mmap.mmap(f.fileno(),0,access=mmap.ACCESS_READ))as m:
print ‘first 10 red:‘,m.read(10)
print ‘first 10 slice:‘,m[:10]
print ‘2nd:‘,m.read(10)
#檔案指定會跟蹤通過一個分區操作訪問最後一個位元組
#寫入
import shutil
shutil.copyfile(‘text.txt‘, ‘lorem_copy.txt‘)
word = ‘consectetuer‘
reversed = word[::-1]
print ‘Looking for :‘, word
print ‘Replacing with :‘, reversed
with open(‘lorem_copy.txt‘, ‘r+‘) as f:
with contextlib.closing(mmap.mmap(f.fileno(), 0)) as m:
print ‘Before:‘
print m.readline().rstrip()
m.seek(0) # rewind
loc = m.find(word)
m[loc:loc+len(word)] = reversed
m.flush()
m.seek(0) # rewind
print ‘After :‘
print m.readline().rstrip()
f.seek(0) # rewind
print ‘File :‘
print f.readline().rstrip()
#記憶體和檔案中第一行中間的單詞consectetuer將被替換
#複製模式:使用ACCESS_COPY則不會改變實際儲存的檔案
print ‘copy ‘*20
shutil.copyfile(‘lorem.txt‘, ‘lorem_copy.txt‘)
word = ‘consectetuer‘
reversed = word[::-1]
with open(‘lorem_copy.txt‘, ‘r+‘) as f:
with contextlib.closing(mmap.mmap(f.fileno(), 0,
access=mmap.ACCESS_COPY)
) as m:
print ‘Memory Before:‘
print m.readline().rstrip()
print ‘File Before :‘
print f.readline().rstrip()
print
m.seek(0) # rewind
loc = m.find(word)
m[loc:loc+len(word)] = reversed
m.seek(0) # rewind
print ‘Memory After :‘
print m.readline().rstrip()
f.seek(0)
print ‘File After :‘
print f.readline().rstrip()
#Regex
#由於記憶體對應檔就類似於一個字串,因此也適用其他處理字串模組,如正則
print ‘re ‘*20
pattern = re.compile(r‘(\.\W+)?([^.]?nulla[^.]*?\.)‘,
re.DOTALL | re.IGNORECASE | re.MULTILINE)
with open(‘lorem.txt‘, ‘r‘) as f:
with contextlib.closing(mmap.mmap(f.fileno(), 0,
access=mmap.ACCESS_READ)
) as m:
for match in pattern.findall(m):
print match[1].replace(‘\n‘, ‘ ‘)
#contextlib:使用closing()函數為記憶體對應檔建立一個上下文管理器
python標準庫基礎之mmap:記憶體對應檔