Python中文件I/O高效操纵处理惩罚的能力
如何读写文本文件?
实际案例
某文本文件编码名目已直(如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() 函数,它需要一个打开的文件描写符作为参数
建设如下文件
[[email protected] ~]# 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 # 以十六进制名目查察文件内容 [[email protected] ~]# 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'
查察
[[email protected] ~]# od -x demo.bin 0000000 0088 0000 0000 0000 0000 0000 0000 0000 0000020 0000 0000 0000 0000 0000 0000 0000 0000 * 4000000
修改切片
>>> m[4:8] = '\xff' * 4
#p#分页标题#e#
查察
[[email protected] ~]# 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
查察
[[email protected] ~]# 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
如何会见文件的状态?
实际案例
在某些项目中,我们需要得到文件状态,譬喻:
文件的范例(普通文件、目次、标记链接、设备文件…)
文件的会见权限
文件的最后的会见/修改/节点状态变动时间
普通文件的巨细
…..
办理方案
当前目次有如下文件
[[email protected] 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
系统挪用
尺度库中的os模块下的三个系统挪用 stat 、 fstat 、 lstat 获取文件状态
>>> 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
获取文件的会见权限,只要大于0就为真
>>> 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)
获取普通文件的巨细
>>> s.st_size 0
快捷函数
尺度库中 os.path 下的一些函数,利用起来越发简捷
文件范例判定
>>> 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
获取文件巨细
>>> os.path.getsize('files')
0
如何利用姑且文件?
实际案例
某项目中,我们从传感器收罗数据,每收集到1G数据后,做数据阐明,最终只生存阐明功效,这样很大的姑且数据假如常驻内存,将耗损大量内存资源,我们可以利用姑且文件存储这些姑且数据(外部存储)
姑且文件不消定名,且封锁后会自动被删除
办理方案
利用尺度库中的 tempfile 下的 TemporaryFile, NamedTemporaryFile
>>> from tempfile import TemporaryFile, NamedTemporaryFile
# 会见的时候只能通过工具f来举办会见
>>> f = TemporaryFile()
>>> f.write('abcdef' * 100000)
# 会见姑且数据
>>> f.seek(0)
>>> f.read(100)
'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd'
>>> ntf = NamedTemporaryFile()
# 假如要让每次建设NamedTemporaryFile()工具时不删除文件,可以配置NamedTemporaryFile(delete=False)
>>> ntf.name
# 返回当前姑且文件在文件系统中的路径
'/tmp/tmppNvNA6'