如何读写文本文件?
实际案例
某文本文件编码格式已直(如UTF-8,GBK,BIG5),在python2.x和python3.x中分别如何读取这些文件?
解决方案
字符串的语义发生了变化:
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@iZ28i253je0Z ~]# 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@iZ28i253je0Z ~]# 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@iZ28i253je0Z ~]# 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
查看
[root@iZ28i253je0Z ~]# 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@iZ28i253je0Z ~]# 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
如何访问文件的状态?
实际案例
在某些项目中,我们需要获得文件状态,例如:
- 文件的类型(普通文件、目录、符号链接、设备文件…)
- 文件的访问权限
- 文件的最后的访问/修改/节点状态更改时间
- 普通文件的大小
- …..
解决方案
当前目录有如下文件
[root@iZ28i253je0Z 2016-09-16]# 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=1473996947, st_mtime=1473996947, st_ctime=1473996947) > 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 1473996947.3384445 # 修改时间 > s.st_mtime 1473996947.3384445 # 状态更新时间 > s.st_ctime 1473996947.3384445
将获取到的时间戳进行转换
> 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') 1473996947.3384445 > os.path.getmtime('files') 1473996947.3384445 > os.path.getctime('files') 1473996947.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/tmppNvBu2'
总结
以上就是关于Python中文件I/O高效处理技巧的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]