實際案例
某文字檔案編碼格式已直(如UTF-8,GBK,BIG5),在python2.x和python3.x中分別如何讀取這些文件?
解決方案
注意區分python2和python3中的差異
字串的語意發生了變化:
#python2 | python3 |
#str | bytes |
unicode | str |
python2.x 寫入檔案前對unicode 編碼,讀入檔案後對二進位字串解碼
>>> f = open('py2.txt', 'w') >>> s = u'你好' >>> f.write(s.encode('gbk')) >>> f.close() >>> f = open('py2.txt', 'r') >>> t = f.read() >>> print t.decode('gbk')
你好
python3.x 中open 函數指定t 的文字模式, encoding 指定編碼格式
>>> f = open('py3.txt', 'wt', encoding='utf-8') >>> f.write('你好') 2 >>> f.close() >>> f = open('py3.txt', 'rt', encoding='utf-8') >>> s = f.read() >>> s '你好'
實際案例
將檔案內容寫入到硬碟裝置時,使用系統調用,這類I/O操作的時間很長,為了減少I/O操作的次數,檔案通常使用緩衝區(有足夠的資料才進行系統調用),檔案的快取行為,分為全緩衝、行快取、無緩衝。
如何設定Python中檔案物件的緩衝行文?
解決方案
全緩衝: open 函數的buffering 設定為大於1的整數n,n為緩衝區大小
>>> f = open('demo2.txt', 'w', buffering=2048) >>> f.write('+' * 1024) >>> f.write('+' * 1023) # 大于2048的时候就写入文件 >>> f.write('-' * 2) >>> f.close()
行緩衝: open 函數的buffering 設定為1
>>> f = open('demo3.txt', 'w', buffering=1) >>> f.write('abcd') >>> f.write('1234') # 只要加上\n就写入文件中 >>> f.write('\n') >>> f.close()
無緩衝:open 函數的buffering 設定為0
>>> f = open('demo4.txt', 'w', buffering=0) >>> f.write('a') >>> f.write('b') >>> f.close()
實際案例
在存取某些二進位檔案時,希望能把檔案對應到記憶體中,可以實現隨機存取.(framebuffer裝置檔案)
某些嵌入式設備,暫存器唄編址到記憶體位址空間,我們可以映射/dev/mem 某個範圍,去存取這些暫存器
如果多個進程映射到同一個文件,還能實現進程通訊的目的
解決方案
使用標準庫中的mmap 模組的mmap() 函數,它需要一個打開的檔案描述符作為參數
創建如下檔案
[root@pythontab.com ~]# dd if=/dev/zero of=demo.bin bs=1024 count=1024 1024+0 records in 1024+0 records out 1048576 bytes (1.0 MB) copied, 0.00380084 s, 276 MB/s # 以十六进制格式查看文件内容 [root@pythontab.com ~]# od -x demo.bin 0000000 0000 0000 0000 0000 0000 0000 0000 0000 * 4000000
>>> import mmap >>> import os >>> f = open('demo.bin','r+b') # 获取文件描述符 >>> f.fileno() 3 >>> m = mmap.mmap(f.fileno(),0,access=mmap.ACCESS_WRITE) >>> type(m) <type 'mmap.mmap'> # 可以通过索引获取内容 >>> m[0] '\x00' >>> m[10:20] '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # 修改内容 >>> m[0] = '\x88'
查看
[root@pythontab.com ~]# od -x demo.bin 0000000 0088 0000 0000 0000 0000 0000 0000 0000 0000020 0000 0000 0000 0000 0000 0000 0000 0000 * 4000000
修改切片
rrreee查看
>>> m[4:8] = '\xff' * 4
[root@pythontab.com ~]# od -x demo.bin 0000000 0088 0000 ffff ffff 0000 0000 0000 0000 0000020 0000 0000 0000 0000 0000 0000 0000 0000 * 4000000
查看
>>> m = mmap.mmap(f.fileno(),mmap.PAGESIZE * 8,access=mmap.ACCESS_WRITE,offset=mmap.PAGESIZE * 4) >>> m[:0x1000] = '\xaa' * 0x1000
實際案例
在某些項目中,我們需要取得檔案狀態,例如:
#檔案的類型(普通檔案、目錄、符號連結、裝置檔案…)
檔案的存取權限
檔案的最後的存取/修改/節點狀態變更時間
普通檔案的大小
…..
解決方案
目前目錄有以下檔案
[root@pythontab.com ~]# od -x demo.bin 0000000 0088 0000 ffff ffff 0000 0000 0000 0000 0000020 0000 0000 0000 0000 0000 0000 0000 0000 * 0040000 aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa * 0050000 0000 0000 0000 0000 0000 0000 0000 0000 * 4000000
系統呼叫
#標準函式庫中的os模組下的三個系統呼叫stat 、 fstat 、 lstat 取得檔案狀態
[root@pythontab.com 2017]# ll total 4 drwxr-xr-x 2 root root 4096 Sep 16 11:35 dirs -rw-r--r-- 1 root root 0 Sep 16 11:35 files lrwxrwxrwx 1 root root 37 Sep 16 11:36 lockfile -> /tmp/qtsingleapp-aegisG-46d2-lockfile
取得檔案的存取權限,只要大於0就為真
>>> import os >>> s = os.stat('files') >>> s posix.stat_result(st_mode=33188, st_ino=267646, st_dev=51713L, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1486197100, st_mtime=1486197100, st_ctime=1486197100) >>> s.st_mode 33188 >>> import stat # stat有很多S_IS..方法来判断文件的类型 >>> stat.S_ISDIR(s.st_mode) False # 普通文件 >>> stat.S_ISREG(s.st_mode) True
取得檔案的修改時間
>>> s.st_mode & stat.S_IRUSR 256 >>> s.st_mode & stat.S_IXGRP 0 >>> s.st_mode & stat.S_IXOTH 0
將取得到的時間戳進行轉換
# 访问时间 >>> s.st_atime 1486197100.3384446 # 修改时间 >>> s.st_mtime 1486197100.3384446 # 状态更新时间 >>> s.st_ctime 1486197100.3384446
取得普通檔案的大小
>>> import time >>> time.localtime(s.st_atime) time.struct_time(tm_year=2016, tm_mon=9, tm_mday=16, tm_hour=11, tm_min=35, tm_sec=47, tm_wday=4, tm_yday=260, tm_isdst=0)
快捷函數
標準庫中os.path 下的一些函數,使用起來更加簡潔
檔案類型判斷
>>> s.st_size 0
檔案三個時間
>>> os.path.isdir('dirs') True >>> os.path.islink('lockfile') True >>> os.path.isfile('files') True
取得檔案大小
>>> os.path.getatime('files') 1486197100.3384445 >>> os.path.getmtime('files') 1486197100.3384445 >>> os.path.getctime('files') 1486197100.3384445
實際案例
某專案中,我們從感測器收集數據,每收集到1G數據後,做數據分析,最終只保存分析結果,這樣很大的臨時數據如果常駐內存,將消耗大量內存資源,我們可以使用臨時檔案存儲這些臨時資料(外部存儲)
臨時檔案不用命名,並且關閉後會自動被刪除
#解決方案
使用標準庫中的tempfile 下的TemporaryFile, NamedTemporaryFile
>>> os.path.getsize('files') 0
以上是使用Python中文件I/O高效操作處理的技巧分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!