W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
你想內(nèi)存映射一個二進制文件到一個可變字節(jié)數(shù)組中,目的可能是為了隨機訪問它的內(nèi)容或者是原地做些修改。
使用 mmap
模塊來內(nèi)存映射文件。下面是一個工具函數(shù),向你演示了如何打開一個文件并以一種便捷方式內(nèi)存映射這個文件。
import os
import mmap
def memory_map(filename, access=mmap.ACCESS_WRITE):
size = os.path.getsize(filename)
fd = os.open(filename, os.O_RDWR)
return mmap.mmap(fd, size, access=access)
為了使用這個函數(shù),你需要有一個已創(chuàng)建并且內(nèi)容不為空的文件。下面是一個例子,教你怎樣初始創(chuàng)建一個文件并將其內(nèi)容擴充到指定大?。?/p>
>>> size = 1000000
>>> with open('data', 'wb') as f:
... f.seek(size-1)
... f.write(b'\x00')
...
>>>
下面是一個利用 memory_map()
函數(shù)類內(nèi)存映射文件內(nèi)容的例子:
>>> m = memory_map('data')
>>> len(m)
1000000
>>> m[0:10]
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> m[0]
0
>>> # Reassign a slice
>>> m[0:11] = b'Hello World'
>>> m.close()
>>> # Verify that changes were made
>>> with open('data', 'rb') as f:
... print(f.read(11))
...
b'Hello World'
>>>
mmap()
返回的 mmap
對象同樣也可以作為一個上下文管理器來使用,這時候底層的文件會被自動關閉。比如:
>>> with memory_map('data') as m:
... print(len(m))
... print(m[0:10])
...
1000000
b'Hello World'
>>> m.closed
True
>>>
默認情況下,memeory_map()
函數(shù)打開的文件同時支持讀和寫操作。任何的修改內(nèi)容都會復制回原來的文件中。如果需要只讀的訪問模式,可以給參數(shù) access
賦值為 mmap.ACCESS_READ
。比如:
m = memory_map(filename, mmap.ACCESS_READ)
如果你想在本地修改數(shù)據(jù),但是又不想將修改寫回到原始文件中,可以使用 mmap.ACCESS_COPY
:
m = memory_map(filename, mmap.ACCESS_COPY)
為了隨機訪問文件的內(nèi)容,使用 mmap
將文件映射到內(nèi)存中是一個高效和優(yōu)雅的方法。例如,你無需打開一個文件并執(zhí)行大量的 seek()
,read()
,write()
調用,只需要簡單的映射文件并使用切片操作訪問數(shù)據(jù)即可。
一般來講,mmap()
所暴露的內(nèi)存看上去就是一個二進制數(shù)組對象。但是,你可以使用一個內(nèi)存視圖來解析其中的數(shù)據(jù)。比如:
>>> m = memory_map('data')
>>> # Memoryview of unsigned integers
>>> v = memoryview(m).cast('I')
>>> v[0] = 7
>>> m[0:4]
b'\x07\x00\x00\x00'
>>> m[0:4] = b'\x07\x01\x00\x00'
>>> v[0]
263
>>>
需要強調的一點是,內(nèi)存映射一個文件并不會導致整個文件被讀取到內(nèi)存中。也就是說,文件并沒有被復制到內(nèi)存緩存或數(shù)組中。相反,操作系統(tǒng)僅僅為文件內(nèi)容保留了一段虛擬內(nèi)存。當你訪問文件的不同區(qū)域時,這些區(qū)域的內(nèi)容才根據(jù)需要被讀取并映射到內(nèi)存區(qū)域中。而那些從沒被訪問到的部分還是留在磁盤上。所有這些過程是透明的,在幕后完成!
如果多個Python解釋器內(nèi)存映射同一個文件,得到的 mmap
對象能夠被用來在解釋器直接交換數(shù)據(jù)。也就是說,所有解釋器都能同時讀寫數(shù)據(jù),并且其中一個解釋器所做的修改會自動呈現(xiàn)在其他解釋器中。很明顯,這里需要考慮同步的問題。但是這種方法有時候可以用來在管道或套接字間傳遞數(shù)據(jù)。
這一小節(jié)中函數(shù)盡量寫得很通用,同時適用于Unix和Windows平臺。要注意的是使用 mmap()
函數(shù)時會在底層有一些平臺的差異性。另外,還有一些選項可以用來創(chuàng)建匿名的內(nèi)存映射區(qū)域。如果你對這個感興趣,確保你仔細研讀了Python文檔中這方面的內(nèi)容 。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: