一. 如何將文件映射到內(nèi)存办悟?
實(shí)際案例:
- 在訪問(wèn)某些二進(jìn)制文件時(shí)。希望能把文件映射到內(nèi)存中惜姐,可以實(shí)現(xiàn)隨機(jī)訪問(wèn)牵敷。(framebuffer設(shè)備文件)
- 某些嵌入式設(shè)備胡岔,寄存器被編址到內(nèi)存地址空間,我們可以映射/dev/mem某范圍劣领,去訪問(wèn)這些寄存器姐军。
- 如果多個(gè)進(jìn)程映射同一個(gè)文件,還能實(shí)現(xiàn)進(jìn)程通信的目的尖淘。
解決方案:
- 使用標(biāo)準(zhǔn)庫(kù)中mmap模塊中的mmap()函數(shù),它需要一個(gè)打開(kāi)的文件描述符作為參數(shù)著觉。
代碼示例:
# _*_ coding:utf-8 _*_
# @Author : TianYu
# @Time : 2017/10/16 14:01
# @File : 如何將文件映射到內(nèi)存.py
#使用標(biāo)準(zhǔn)庫(kù)中的mmap模塊的mmap()函數(shù)村生,它需要一個(gè)打開(kāi)的文件描述符作為參數(shù)
#首先:Linux下利用 dd 命令創(chuàng)建一個(gè)大小為 1M ,每個(gè)字節(jié)都是 0 的二進(jìn)制文件demo.bin
# dd if=/dev/zero of=demo.bin bs=1024 count=1024
#接下來(lái):使用 dd -x demo.bin 命令以十六進(jìn)制的形式查看文件
#之后進(jìn)行映射:
import mmap
# mmap.mmap在不同的系統(tǒng)下使用有一些差別
#Windows:mmap(fileno, length[,tagname[,access[,offset]]])
#Unix: mmap(fileno,length[,flags[,prot[,access[,offset]]])
#fileno:文件描述符(不是文件對(duì)象)饼丘,由系統(tǒng)調(diào)用的open函數(shù)得到的(os模塊下的os.open)
#length:映射區(qū)域的長(zhǎng)度趁桃,為 0 的時(shí)候映射整個(gè)文件
#access:訪問(wèn)權(quán)限
#offset:指定文件映射的某一區(qū)域
f = open('demo.bin', 'r+b') #權(quán)限是 讀寫 二進(jìn)制
f.fileno()#報(bào)告一個(gè)文件描述符
m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_WRITE)
print(type(m)) #是mmap.mmap對(duì)象,可以有類似數(shù)組一樣的操作:引索肄鸽、切片
m[0] = '\x88' #寫操作卫病,修改 0 引索下的內(nèi)容,利用 od -x 命令(Linux下)可以查看文件的變化
m[4:8] = '\xff' * 4 #修改的字符串的長(zhǎng)度一定要和切片的長(zhǎng)度一致
#注意:mmap函數(shù)它必須是“以內(nèi)存頁(yè)的大小進(jìn)行對(duì)齊的”offset不能指定跳過(guò)文件的 3或5個(gè)字節(jié)
m = mmap.mmap(f.fileno(), mmap.PAGESIZE * 8, access=mmap.ACCESS_WRITE, offset=mmap.PAGESIZE * 4)
m[:0x1000] = '\xaa' * 0x1000 #之后 od -x 進(jìn)行查看文件
二. 如何訪問(wèn)文件的狀態(tài)典徘?
實(shí)際案例:
在某些項(xiàng)目中蟀苛,我們需要獲得文件狀態(tài),例如:
- 文件的類型(普通文件逮诲,目錄帜平,符號(hào)鏈接,設(shè)備文件...)
- 文件的訪問(wèn)權(quán)限
- 文件的最后的訪問(wèn)/修改/節(jié)點(diǎn)狀態(tài)更改時(shí)間
- 普通文件的大小
......
解決方案:
1.系統(tǒng)調(diào)用:標(biāo)準(zhǔn)庫(kù)中os模塊下的三個(gè)系統(tǒng)調(diào)用stat, fstat, lstat獲取文件狀態(tài)
- 快捷函數(shù):標(biāo)準(zhǔn)庫(kù)中os.path下一些函數(shù)梅鹦,使用起來(lái)更加簡(jiǎn)潔裆甩。
代碼示例:
# _*_ coding:utf-8 _*_
# @Author : TianYu
# @Time : 2017/10/16 14:34
# @File : 如何訪問(wèn)文件的狀態(tài).py
import os ,stat
#方法 1 :系統(tǒng)調(diào)用:使用標(biāo)準(zhǔn)庫(kù)中os模塊下的三個(gè)系統(tǒng)調(diào)用stat, fstat, lstat獲取文件狀態(tài)
#stat(path)
#lstat(path):區(qū)別是lstat不跟隨符號(hào)鏈接
#fstat(fd):傳入的參數(shù)是一個(gè)打開(kāi)的文件描述符 f.fileno()可以獲得
s = os.stat('a1.txt')
bin(s.st_mode) #s.st_mode是一個(gè)數(shù),由一些標(biāo)志位構(gòu)成齐唆,用bin轉(zhuǎn)化為二進(jìn)制
stat.S_ISDIR(s.st_mode) #判斷文件是否是一個(gè)文件夾
stat.S_ISREG(s.st_mode) #判斷普通文件
print(s.st_mode & stat.S_IRUSR)#判斷用戶的讀權(quán)限嗤栓,只要值大于 0 ,代表為True
print(s.st_mode & stat.S_IXUSR)#判斷文件的執(zhí)行權(quán)限
import time
time.localtime(s.st_atime) #文件的最后訪問(wèn)/修改/節(jié)點(diǎn)狀態(tài)更改時(shí)間
print(s.st_size) #普通文件的大小
#方法 2:快捷函數(shù):使用標(biāo)準(zhǔn)庫(kù)中os.path下一些函數(shù)箍邮,使用起來(lái)更加簡(jiǎn)潔
os.path.isdir('a1.txt')#判斷是否是一個(gè)目錄
os.path.islink('a1.txt')#判斷是否是一個(gè)符號(hào)鏈接
os.path.isfile('a1.txt') #判斷是否是一個(gè)普通文件
os.path.getatime('a1.txt') #最后修改時(shí)間
os.path.getsize('a1.txt')#普通文件的大小
三. 如何使用臨時(shí)文件茉帅?
實(shí)際案例:
- 某項(xiàng)目中,我們從傳感器采集數(shù)據(jù)媒殉,每收到 1G 數(shù)據(jù)后担敌,做數(shù)據(jù)分析,最終只保存分析結(jié)果廷蓉。這樣很大的臨時(shí)數(shù)據(jù)如果常駐內(nèi)存全封,將消耗大量?jī)?nèi)存資源马昙,我們可以使用臨時(shí)文件存儲(chǔ)這些臨時(shí)數(shù)據(jù)(外部存儲(chǔ))。
臨時(shí)文件不用命名刹悴,且關(guān)閉后會(huì)自動(dòng)被刪除行楞。
解決方案:
- 使用標(biāo)準(zhǔn)庫(kù)中的temporaryFile, namedTemporaryFile對(duì)象土匀。
代碼示例:
# _*_ coding:utf-8 _*_
# @Author : TianYu
# @Time : 2017/10/16 15:00
# @File : 如何使用臨時(shí)文件.py
#使用臨時(shí)文件不用命名子房,且關(guān)閉后會(huì)自動(dòng)被刪除
#使用標(biāo)準(zhǔn)庫(kù)中tempfile下的TemporaryFile, NamedTemporaryFile對(duì)象
from tempfile import TemporaryFile, NamedTemporaryFile
#TemporaryFile:默認(rèn)情況下以 w+b(讀寫,二進(jìn)制) 的權(quán)限打開(kāi)的
#NamedTemporaryFile:帶名字的臨時(shí)文件
f = TemporaryFile()#一個(gè)臨時(shí)文件的對(duì)象就轧,不能由系統(tǒng)的文件系統(tǒng)路徑找到证杭,只能由對(duì)象f訪問(wèn)
f.write('abcdef' * 100000) #讀寫臨時(shí)數(shù)據(jù)
f.seek(0)#收集完畢后,讀會(huì)內(nèi)存中需向?qū)?文件指針指向文件頭部
f.read(100) #每次讀入臨時(shí)文件中的一小部分?jǐn)?shù)據(jù)
ntf = NamedTemporaryFile()
print(ntf.name()) #描述了ntf在文件系統(tǒng)路徑下的字段,每次關(guān)閉后會(huì)刪除
nft = NamedTemporaryFile(delete=False) #參數(shù)delete變?yōu)镕alse妒御,關(guān)閉后解愤,文件系統(tǒng)路徑字段不會(huì)刪除
print(ntf.name())
要努力要奮斗