PythonCookBook笔记——文件与IO
文件与IO
所有的程序都要处理输入与输出,涉及到文本、二进制文件、文件编码和对文件名、目录的操作。
读写文本数据
需要读写各种不同编码的文本数据,使用rt模式的open()函数。
该读写操作使用系统默认编码,可通过sys.getdefaultencoding()来得到,大部分都是utf-8。
打印输出到文件中
将print()函数的输出重定向到文件中。
# 指定file关键字参数,文件必须是文本形式打开
with open('d:/work/test.txt', 'wt') as f:
print('Hello World!', file=f)
使用其它分割符或行终止符打印
调用print()方法的sep和end关键字。
>>> print('ACME', 50, 91.5)
ACME 50 91.5
>>> print('ACME', 50, 91.5, sep=',')
ACME,50,91.5
>>> print('ACME', 50, 91.5, sep=',', end='!!\n')
ACME,50,91.5!!
>>>
读写字节数据
使用rb或wb的open()函数来读写二进制数据。
# Read the entire file as a single byte string
with open('somefile.bin', 'rb') as f:
data = f.read()
# Write binary data to a file
with open('somefile.bin', 'wb') as f:
f.write(b'Hello World')
数组对象和C结构体可以直接当作字节数据写入。
文件不存在才能写入
有时怕覆盖了已存在的文件,可以使用x模式代替w模式的open()函数,对已存在的文件会throw一个FileExistsError。
如果文件是二进制的,使用xb代替xt。
x模式是在python3中对open()的特有拓展,在低版本中没有这个模式。
字符串的IO操作
想用操作类文件对象的程序来操作文本或二进制字串,使用io.StringIO()和io.BytesIO()来操作字符串数据。
>>> s = io.StringIO()
>>> s.write('Hello World\n')
12
>>> print('This is a test', file=s)
15
>>> # Get all of the data written so far
>>> s.getvalue()
'Hello World\nThis is a test\n'
>>>
>>> # Wrap a file interface around an existing string
>>> s = io.StringIO('Hello\nWorld\n')
>>> s.read(4)
'Hell'
>>> s.read()
'o\nWorld\n'
>>>
io.StringIO只能用于文本,对二进制数据使用io.BytesIO。
>>> s = io.BytesIO()
>>> s.write(b'binary data')
>>> s.getvalue()
b'binary data'
>>>
读写压缩文件
读写一个gzip或bz2格式的压缩文件,使用gzip和bz2模块,都提供了open()函数来实现。
# gzip compression
import gzip
with gzip.open('somefile.gz', 'rt') as f:
text = f.read()
# bz2 compression
import bz2
with bz2.open('somefile.bz2', 'rt') as f:
text = f.read()
这两个模块提供的open()函数接收与内置函数一样的参数,还提供compresslevel这个新参数用于指定压缩级别,默认最高级别9,等级越低性能越好。
并且可以作用在一个已被打开的文件上。
import gzip
f = open('somefile.gz', 'rb')
with gzip.open(f, 'rt') as g:
text = g.read()
固定大小记录的文件迭代
想在一个固定长度记录或数据块的集合上迭代,而不是在文件中一行行迭代。
使用iter和functools.partial()函数。
from functools import partial
RECORD_SIZE = 32
with open('somefile.data', 'rb') as f:
records = iter(partial(f.read, RECORD_SIZE), b'')
for r in records:
...
读取二进制数据到可变缓冲区
想直接读取二进制数据到一个可变缓冲区中,而不做任何中间复制操作,或原地修改数据并写回到文件中去。
使用文件的readinto()方法。
import os.path
def read_into_buffer(filename):
buf = bytearray(os.path.getsize(filename))
with open(filename, 'rb') as f:
f.readinto(buf)
return buf
>>> # Write a sample file
>>> with open('sample.bin', 'wb') as f:
... f.write(b'Hello World')
...
>>> buf = read_into_buffer('sample.bin')
>>> buf
bytearray(b'Hello World')
>>> buf[0:5] = b'Hello'
>>> buf
bytearray(b'Hello World')
>>> with open('newsample.bin', 'wb') as f:
... f.write(buf)
...
11
>>>
f.readinto()的返回值为实际读取的字节数,因此要检查其值是否小于期望值。
文件路径名的操作
通过os.path模块的函数来操作路径名。
os.path.basename(path)获取最后一级的文件名。
os.path.dirname(path)获取除文件名的所有路径。
os.path.join(path1, path2, path3)将所有路径按顺序拼接起来,等效于加法。
测试文件是否存在
os.path.exists(path)用于检测文件或目录是否存在。
os.path.isfile(path)检测是否是文件。
os.path.isdir(path)检测是否是目录。
os.path.islink(path)检测是否是链接文件。
os.path.realpath(path)获取链接文件的真实文件路径。
os.path.getsize(path)获取文件大小。
os.path.getmtime(path)获取文件修改时间。
获取文件夹中的文件列表
获取文件系统中某个目录下的所有文件列表。
os.listdir(path)返回目录中所有文件列表、子目录、符号链接。
import os.path
# Get all regular files
names = [name for name in os.listdir('somedir')
if os.path.isfile(os.path.join('somedir', name))]
# Get all dirs
dirnames = [name for name in os.listdir('somedir')
if os.path.isdir(os.path.join('somedir', name))]
也可以通过字串的startswith()和endswith()方法过滤内容。
pyfiles = [name for name in os.listdir('somedir')
if name.endswith('.py')]
打印不合法的文件名
针对文件名出现UnicodeEncodeError和surrogates not allowed异常和消息,通过辅助函数处理该错误。
def bad_filename(filename):
return repr(filename)[1:-1]
try:
print(filename)
except UnicodeEncodeError:
print(bad_filename(filename))
增加和改变已打开文件的编码
想在不关闭一个已打开的文件前提下增加或改变其Unicode编码。
为一个二进制模式打开的文件添加Unicode编解码方式,使用io.TextIOWrapper()包装。
import urllib.request
import io
u = urllib.request.urlopen('http://www.python.org')
f = io.TextIOWrapper(u, encoding='utf-8')
text = f.read()
将字节写入文本文件
写入文件的缓冲区即可。
>>> import sys
>>> sys.stdout.write(b'Hello\n')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: must be str, not bytes
>>> sys.stdout.buffer.write(b'Hello\n')
Hello
5
>>>
文本文件buffer属性来读取二进制数据。
将文件描述符包装成文件对象
一个文件描述符和一个打开的普通文件是不一样的,文件描述符是系统指定的整数用来指代某个系统的IO通道,可以通过将该描述符作为文件名来打开open()函数。
# Open a low-level file descriptor
import os
fd = os.open('somefile.txt', os.O_WRONLY | os.O_CREAT)
# Turn into a proper file
f = open(fd, 'wt')
f.write('hello world\n')
f.close()
如果不想在高层文件对象关闭的时候关闭底层文件描述符,传递一个可选参数closefd=False。
# Create a file object, but don't close underlying fd when done
f = open(fd, 'wt', closefd=False)
...
创建临时文件和文件夹
需要在程序执行时创建一个临时文件或目录,并希望用完之后可以自动销毁。
tempfile模块提供了很多函数。
tempfile.TemporaryFile()创建匿名临时文件。
from tempfile import TemporaryFile
with TemporaryFile('w+t') as f:
# Read/write to the file
f.write('Hello World\n')
f.write('Testing\n')
# Seek back to beginning and read the data
f.seek(0)
data = f.read()
# Temporary file is destroyed
tempfile.NamedTemporaryFile()创建命名临时文件,可通过f.name访问其名称。
temfile.TemporaryDirectory()创建临时文件夹。
与串行端口的数据通信
与一些硬件设备通信,最好使用pySerial包。
序列化Python对象
最普遍的是pickle模块。
s = pickle.dumps(data)
data = pickle.loads(s)
不要对不信任的数据使用pickle.load(),其有个副作用就是自动加载相应模块并构造实例对象。
并且有些类型的对象是不能被序列化的,通常是依赖外部系统状态的对象,如打开的文件、网络链接、线程、进程、栈帧等,用户自定义类可以通过__getstate__()和__setstate__()方法来绕过该限制。
# countdown.py
import time
import threading
class Countdown:
def __init__(self, n):
self.n = n
self.thr = threading.Thread(target=self.run)
self.thr.daemon = True
self.thr.start()
def run(self):
while self.n > 0:
print('T-minus', self.n)
self.n -= 1
time.sleep(5)
def __getstate__(self):
return self.n
def __setstate__(self, n):
self.__init__(n)
>>> import countdown
>>> c = countdown.Countdown(30)
>>> T-minus 30
T-minus 29
T-minus 28
...
>>> # After a few moments
>>> f = open('cstate.p', 'wb')
>>> import pickle
>>> pickle.dump(c, f)
>>> f.close()
>>> f = open('cstate.p', 'rb')
>>> pickle.load(f)
countdown.Countdown object at 0x10069e2d0>
T-minus 19
T-minus 18
...
pickle是附着在源码上的,如果需要在数据库或文档中存储数据,最好使用XML、CSV、JSON等格式。
PythonCookBook笔记——文件与IO的更多相关文章
- Java基础复习笔记系列 七 IO操作
Java基础复习笔记系列之 IO操作 我们说的出入,都是站在程序的角度来说的.FileInputStream是读入数据.?????? 1.流是什么东西? 这章的理解的关键是:形象思维.一个管道插入了一 ...
- jQuery整理笔记文件夹
jQuery整理笔记文件夹 jQuery整理笔记一----jQuery開始 jQuery整理笔记二----jQuery选择器整理 jQuery整理笔记三----jQuery过滤函数 jQuery整理笔 ...
- node源码详解(七) —— 文件异步io、线程池【互斥锁、条件变量、管道、事件对象】
本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/nodesource7 本博客同步在https://cnodejs.o ...
- Java基础学习笔记二十 IO流
转换流 在学习字符流(FileReader.FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者OutputStre ...
- Python编程从入门到实践笔记——文件
Python编程从入门到实践笔记——文件 #coding=gbk #Python编程从入门到实践笔记——文件 #10.1从文件中读取数据 #1.读取整个文件 file_name = 'pi_digit ...
- 文件和IO流
摘要:本文主要介绍了Java的文件处理以及常用的IO流操作. 文件操作 概念 File是数据源(保存数据的地方)的一种,可以表示一个文件,也可以表示一个文件目录. File类只能对文件和文件夹进行创建 ...
- Atitit.跨语言 文件夹与文件的io操作集合 草案
Atitit.跨语言 文件夹与文件的io操作集合 草案 1. Jdk原生的太难用了..1 2. PS: apache commons-io包,FileUtils有相关的方法,IOUtils一般是拷 ...
- 《python基础教程(第二版)》学习笔记 文件和素材(第11章)
<python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...
- 提高生产力:文件和IO操作(ApacheCommonsIO-汉化分享)
复制.移动.删除.比较.监控.文件读写 等文件和IO操作是编程中比较常用的功能. 幸运的是,Apache Commons IO等开源组件已经帮我们实现了. 我们可以不用重复 ...
随机推荐
- 微信小程序红包开发思路 微信红包小程序开发思路讲解
之前公司开发小程序红包,将自己在开发的过程中遇到的一些坑分享到了博客里.不少人看了以后,还是不明白怎么开发.也加了我微信咨询.所以今天,我就特意再写一篇文章,这次就不谈我开发中遇到的坑了.就主要给大家 ...
- JDBC链接mysql,时间时0000-00-00 00:00:00时报错
应为mysql默认最小timestamp是0001-01-01 00:00:00,所以查询出来会报错 需要加在链接的url中加入 &zeroDateTimeBehavior=convertTo ...
- SharePoint中使用Global.asax
Global.asax是ASP.Net应用程序的一个文件,用来处理Application级别的事情.可以添加自定义代码到这个文件,详细使用方式见 http://msdn.microsoft.com/e ...
- 【BZOJ4945&&UOJ317】游戏(2-sat,拓扑序)
题意: 思路: 输出方案时有一个优秀的性质可以利用: tarjan缩点之后点所属的分量编号是原图的反的拓扑序 所以只需要在两种方案内找到所属分量编号较小的那个就行了,用来满足(i,i')那个限制 #i ...
- poj 1573(搜索)
Robot Motion Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12351 Accepted: 5982 Des ...
- LeetCode OJ-- Spiral Matrix
https://oj.leetcode.com/problems/spiral-matrix/ 螺旋矩阵,逆着转,输出矩阵中的元素. 在纸上模仿,然后记左上角(l1,l2)右上角(l1,r2),左下角 ...
- [笔记][FPGA]有限状态机FSM学习笔记(三)
0. 简介 在数电FPGA中,FSM是一个重要的部分,藉此可以完成一些复杂算法的硬件实现等.其中有关于FSM的写法按照always块的个数来划分,又分为一段式.两段式.三段式状态机.顾名思义,一段式就 ...
- luogu P2158 [SDOI2008]仪仗队
题目描述 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图 ...
- kettle变量使用
公司项目使用kettle重构之前的取数,先研究下日常的使用. 一.建立数据转换,表数据到表输出,其中表输入数据来自其他业务数据库,通过输入sql执行得到数据. 表输入: 表输出: 设置并行4个线程. ...
- gradle_____最后到齐的构建工具
从今年开始,开始换用gradle 了,个人感觉还好,配置不像maven,一堆xml 文件,一个jar 一行字符,内置的task 和很多.自定义task 也挺简单,比ant简单一些. 简单配置文件示例: ...