使用Python中文件I/O高效操作處理的技巧分享

高洛峰
發布: 2017-03-16 16:16:25
原創
1327 人瀏覽過

如何讀寫文字檔?

實際案例

某文字檔案編碼格式已直(如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 &#39;mmap.mmap&#39;>
# 可以通过索引获取内容
>>> 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
登入後複製

修改切片

r​​rreee

查看

>>> 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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!