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

如何读写文本文件?

实际案例

某文本文件编码格式已直(如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()

如何将文件映射到内存?

实际案例

  1. 在访问某些二进制文件时,希望能把文件映射到内存中,可以实现随机访问.(framebuffer设备文件)
  2. 某些嵌入式设备,寄存器呗编址到内存地址空间,我们可以映射 /dev/mem 某范围,去访问这些寄存器
  3. 如果多个进程映射到同一个文件,还能实现进程通信的目的

解决方案

使用标准库中的 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高效处理技巧的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • python处理文本文件实现生成指定格式文件的方法

    本文所述实例为Python处理文本文件并生成指定格式文件的方法,具体实现功能代码如下所示: import os import sys import string #以指定模式打开指定文件,获取文件句柄 def getFileIns(filePath,model): print("打开文件") print(filePath) print(model) return open(filePath,model) #获取需要处理的文件 def getProcFile(path): return

  • 详细讲解Python中的文件I/O操作

    本章将覆盖所有在Python中使用的基本I/O功能.有关更多函数,请参考标准Python文档. 打印到屏幕上: 产生输出最简单的方法是使用print语句,可以通过用逗号分隔的零个或多个表达式.该函数将传递到一个字符串表达式,并将结果写到标准输出,如下所示: #!/usr/bin/python print "Python is really a great language,", "isn't it?"; 这将产生结果输出在标准屏幕上,结果如下: Python is

  • python高手之路python处理excel文件(方法汇总)

    用python来自动生成excel数据文件.python处理excel文件主要是第三方模块库xlrd.xlwt.xluntils和pyExcelerator,除此之外,python处理excel还可以用win32com和openpyxl模块. 方法一: 小罗问我怎么从excel中读取数据,然后我百了一番,做下记录 excel数据图(小罗说数据要给客户保密,我随手写了几行数据): python读取excel文件代码: #!/usr/bin/env python # -*- coding: utf-

  • python处理文本文件并生成指定格式的文件

    import os import sys import string #以指定模式打开指定文件,获取文件句柄 def getFileIns(filePath,model): print("打开文件") print(filePath) print(model) return open(filePath,model) #获取需要处理的文件 def getProcFile(path): return os.listdir(path) #判断是否满足某个条件,如果满足则执行 def isTru

  • python处理PHP数组文本文件实例

    需求: 对一个配置文件进行处理,拿出可用的字符来拼接,下面是原始文本,我们要得到这样的结果, 复制代码 代码如下: redis -h 127.0.0.1 -p 6379 | select 2 redis -h 127.0.0.1 -p 6379 | select 16 redis -h 127.0.0.1 -p 6379 | select 8 原始文本: 复制代码 代码如下: 'redis_list' => array(         'normal' => array(          

  • python读文件逐行处理的示例代码分享

    复制代码 代码如下: import os ## for os.path.isfile() def dealline(line) :    print(line) ## 针对line我可以做很多事情 def getfilename() :    return input('Please input file name(input exit() for exit):').strip() class more : ## MORE功能    linenum = 0    size = 10    def

  • Python文件处理

    本文给大家介绍Python文件处理相关知识,具体内容如下所示: 1.文件的常见操作 文件是日常编程中常用的操作,通常用于存储数据或应用系统的参数.python提供了os.os.path.shutil等模块处理文件,其中包括最常用的打开文件,读写文件,赋值文件和删除文件等函数. 1.1文件的创建 python3.+中移除了python2中的全局file()函数,还保留了open()函数.文件的打开或创建可以使用函数open().该函数可以指定处理模式,设置打开的文件为只读,只写,可读写状态.ope

  • python实现带错误处理功能的远程文件读取方法

    本文实例讲述了python实现带错误处理功能的远程文件读取方法.分享给大家供大家参考.具体如下: import socket, sys, time host = sys.argv[1] textport = "80" filename = sys.argv[3] try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) port = int(textport) s.connect((host, port)) fd = s.ma

  • 实例Python处理XML文件的方法

    需求 有一个表,里面数据量比较大,每天一更新,其字段可以通过xml配置文件进行配置,即,可能每次建表的字段不一样. 上游跑时会根据配置从源文件中提取,到入库这一步需要根据配置进行建表. 解决 写了一个简单的xml,配置需要字段及类型 上游读取到对应的数据 入库这一步,先把原表删除,根据配置建新表 XML文件 <?xml version="1.0" encoding="UTF-8"?> <!-- 表名 ,数据库名 可灵活配置插入哪个库哪个表 --&g

  • Python open()文件处理使用介绍

    1. open()语法 open(file[, mode[, buffering[, encoding[, errors[, newline[, closefd=True]]]]]]) open函数有很多的参数,常用的是file,mode和encoding file文件位置,需要加引号 mode文件打开模式,见下面3 buffering的可取值有0,1,>1三个,0代表buffer关闭(只适用于二进制模式),1代表line buffer(只适用于文本模式),>1表示初始化的buffer大小:

随机推荐