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等开源组件已经帮我们实现了. 我们可以不用重复 ...
随机推荐
- PAT 甲级 1003. Emergency (25)
1003. Emergency (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue As an emerg ...
- Firmware 加载原理分析【转】
转自:http://blog.csdn.net/dxdxsmy/article/details/8669840 [-] 原理分析 实现机制 总结 前言 前段时间移植 wifi 驱动到 Androi ...
- Scrapy学习-18-去重原理
Scrapy去重原理 scrapy本身自带一个去重中间件 scrapy源码中可以找到一个dupefilters.py去重器 源码去重算法 # 将返回值放到集合set中,实现去重 def reque ...
- Delphi GDI对象之绘制位图
http://www.cnblogs.com/pchmonster/archive/2012/07/06/2579334.html 绘制位图(Drawing Bitmaps) 绘制位图听起来似乎很难, ...
- AC日记——Pupils Redistribution Codeforces 779a
A. Pupils Redistribution time limit per test 1 second memory limit per test 256 megabytes input stan ...
- Codeforces 946 B.Weird Subtraction Process
B. Weird Subtraction Process time limit per test 1 second memory limit per test 256 megabytes inpu ...
- Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)
题目链接 Tree and Queries 题目大意 给出一棵树和每个节点的颜色.每次询问$vj, kj$ 你需要回答在以$vj$为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少 ...
- 思科CCIE全新升级,SDN/SD-WAN成重头戏!
CCIE,全称Cisco Certified Internetwork Expert,是美国Cisco公司于1993年开始推出的专家级认证考试.被全球公认为IT业最权威的认证,是全球Internetw ...
- android-samples-mvp
Model–view–presenter (MVP)介绍 mvp在wiki上的介绍为 Model 定义用户界面所需要被显示的数据模型,一个模型包含着相关的业务逻辑 View View不应该处理业务 ...
- java retry:详解
发现 今天在探秘线程池原理知识点,在阅读JDK源码时遇到程序代码中出现如下代码,因为之前没有遇到过,于是特地记录下来并谷歌了一番,后面我自己做了一些简要的验证和分析. 验证 网上溜达一番发现,这ret ...