Python学习--13 文件I/O
Python内置了读写文件的函数,用法和C是兼容的。
读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
读取文件内容
# coding: utf-8
f = open('test.txt', 'r')
print(f.read())
f.close()
输出:
Hello world!
Python
标示符'r'表示读。
如果打开的文件不存在,会直接报错:
Traceback (most recent call last):
File "/Projects/python/code/file.py", line 3, in <module>
f = open('test.txt1', 'r')
IOError: [Errno 2] No such file or directory: 'test.txt1'
报错后,后面的f.close()
不会调用。一般我们会使用try ... finally
来操作文件:
try:
f = open('test.txt', 'r')
print(f.read())
finally:
if f:
f.close()
但是每次都这么写还是太繁琐,所以,Python引入了with
语句来自动帮我们调用close()
方法:
with open('test.txt', 'r') as f:
print(f.read())
这和前面的try ... finally
是一样的,但是代码更佳简洁,并且不必调用f.close()
方法。
如果文件很大,使用read()
方法一下子读到内存,内存会占满。保险起见,可以反复调用read(size)
方法,每次最多读取size
个字节的内容。
另外,调用readline()
可以每次读取一行内容,调用readlines()
一次读取所有内容并按行返回list:
with open('test.txt', 'r') as f:
for line in f.readlines():
print(line)
打开二进制文件
要读取二进制文件(例如图片、音频、视频)内容,使用rb
模式打开:
>>> f = open('test.jpg', 'rb')
>>> f.read()
b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节
读取非utf-8编码的文本
如果要读取非utf-8编码的文本,需要给open()
传入编码参数encoding
,默认是utf-8:
>>> f = open('gbk.txt', 'r', encoding = 'gbk')
>>> f.read()
'测试GBK'
如果不传入,读取的内容是乱码的。
open()
还支持第4个参数errors
,用于当读取的内容编码不规范(会返回UnicodeDecodeError错误),示例:
>>> f = open('gbk.txt', 'r', encoding = 'gbk', errors='ignore')
这样将忽略错误。
写入内容到文件
with open('test.txt', 'w') as f:
f.write('test\n')
要写入特定编码的文本文件,请给open()
函数传入encoding
参数,将字符串自动转换成指定编码。
读取大文件方法
方法一:将文件切分成小段,每次处理完小段,释放内存
def read_in_block(file_path):
BLOCK_SIZE=1024
with open(file_path,"r") as f:
while True:
block =f.read(BLOCK_SIZE) #每次读取固定长度到内存缓冲区
if block:
yield block
else:
return #如果读取到文件末尾,则退出
for block in read_in_block(file_path):
print block
这个方法,速度很快,但有个问题,若满足了1024时,会将正好在1024位置的数据切开。
方法二:利用open()
方法生成的迭代对象:
with open(file_path) as f:
for line in f:
print line
这种用法是把文件对象f当作迭代对象,系统将自动处理IO缓存和内存管理。
耗时较第1种方法慢一点。 但每个Line, type都是str, 都是自己需要的一行数据(一行是一个id)。
文件打开模式
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
file-like Object
像open()
函数返回的这种有个read()
方法的对象,在Python中统称为file-like Object
。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object
不要求从特定类继承,只要写个read()
方法就行。
StringIO
就是在内存中创建的file-like Object
,常用作临时缓冲。
StringIO
StringIO就是在内存中读写str。
读取:
# coding : utf-8
from io import StringIO
with StringIO('hello\nworld\n') as f:
while True:
s = f.readline()
if s == '':
break
print(s.strip())
输出:
hello
world
写入:
from io import StringIO
with StringIO() as f:
f.write('hello\nworld\n')
print(f.getvalue())
输出:
hello
world
getvalue()
方法用于获得写入后的str。
BytesIO
BytesIO就是在内存中读写二进制数据。
写入:
# coding:utf-8
from io import BytesIO
with BytesIO() as f:
f.write('测试Bytes'.encode('utf-8'))
print(f.getvalue())
输出:
b'\xe6\xb5\x8b\xe8\xaf\x95'
注意这里写入的是经过UTF-8编码的bytes。
读取:
# coding:utf-8
from io import BytesIO
with BytesIO(b'\xe6\xb5\x8b\xe8\xaf\x95') as f:
print(f.read())
输出:
b'\xe6\xb5\x8b\xe8\xaf\x95'
StringIO
和BytesIO
是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。
操作文件和目录
Python内置的os
模块可以直接调用操作系统提供的接口函数来操作文件和目录。
查看系统信息
>>> import os
>>> os.name
'nt'
>>> os.environ
environ({'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.wlua;.lexe;.PY', ...})
要获取某个环境变量的值,可以调用os.environ.get('key')
。
unix操作系统提供os.uname()
来获取详细的系统信息。
操作文件和目录
>>> import os
# 查看当前目录的绝对路径:
>>> os.path.abspath('.')
'/Projects/python/code'
# 把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()函数,这样可以正确处理不同操作系统的路径分隔符:
>>> os.path.join('/Projects', 'python')
'/Projects/python'
# 把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名:
>>> os.path.split('/Projects/python/code/os.py')
('/Projects/python/code', 'os.py')
>>> os.path.split('/Projects/python/code/')
('/Projects/python/code', '')
>>> os.path.split('/Projects/python/code')
('/Projects/python', 'code')
# 获取文件扩展名:
>>> os.path.splitext('/Projects/python/code/os.py')
('/Projects/python/code/os', '.py')
# 然后创建一个目录:
>>> os.mkdir('/Projects/python/code/testdir')
# 删掉一个目录:
>>> os.rmdir('/Projects/python/code/testdir')
# 对文件重命名:
>>> os.rename('test.txt', 'test.py')
# 删掉文件:
>>> os.remove('test.py')
复制文件
os
模块中并没有复制文件的方法。原因是复制文件并非由操作系统提供的系统调用。
幸运的是shutil
模块提供了copyfile()
的函数,我们还可以在shutil
模块中找到很多实用函数,它们可以看做是os模块的补充。
# coding : utf-8
import shutil
shutil.copyfile('os.py', 'os2.py')
列出目录内容
# coding : utf-8
import os
dirs = os.listdir('.')
L = []
for d in dirs:
if os.path.isdir(d):
L.append(d)
print(L)
输出:
['.idea', 'class', 'module']
当然,利用Python的列表生成式,可以很简单:
L = [x for x in os.listdir('.') if os.path.isdir(x)]
print(L)
要列出所有的.py
文件:
L = [x for x in os.listdir('.') if os.path.splitext(x)[1] == '.py']
print(L)
输出:
['ostest.py', 'ostest2.py']
参考:
1、python 如何读取大文件 - guohuino2 - 博客园
http://www.cnblogs.com/guohuino2/p/6043196.html
Python学习--13 文件I/O的更多相关文章
- python学习9—文件基本操作与高级操作
python学习9—文件基本操作与高级操作 1. 文件基本操作 打开文件,获得文件句柄:f = open('filename',encoding='utf-8'),open会查询操作系统的编码方式,并 ...
- python学习总结---文件操作
# 文件操作 ### 目录管理(os) - 示例 ```python # 执行系统命令 # 清屏 # os.system('cls') # 调出计算器 # os.system('calc') # 查看 ...
- [Python学习笔记]文件的读取写入
文件与文件路径 路径合成 os.path.join() 在Windows上,路径中以倒斜杠作为文件夹之间的分隔符,Linux或OS X中则是正斜杠.如果想要程序正确运行于所有操作系统上,就必须要处理这 ...
- Python学习_06_文件、IO
文件对象 python中的文件操作和c语言比较类似,包括一些缓冲.偏移量的方式. 文件对象可以通过open().file()两个内建方法创建,两个方法并没有什么不同,使用方法和c语言中的fopen() ...
- python学习笔记:文件操作和集合(转)
转自:http://www.nnzhp.cn/article/16/ 这篇博客来说一下python对文件的操作. 对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句 ...
- python学习——大文件分割与合并
在平常的生活中,我们会遇到下面这样的情况: 你下载了一个比较大型的游戏(假设有10G),现在想跟你的同学一起玩,你需要把这个游戏拷贝给他. 然后现在有一个问题是文件太大(我们不考虑你有移动硬盘什么的情 ...
- python学习8 文件的操作
本文拷贝了on testing 的<python之文件操作:文件的读写>,只做学习之用 python的文件读写通过 一.用open函数 二.对文件读写操作 三.读取文件位置定位 1. op ...
- Python学习——实现文件交互的学生管理系统
第一次用写博客,从前一直在博客园上学习,现在也来这里分享一下我的学习成果. 就开门见山的说吧.首先做了一个流程图,可能也不符合啥规范,就当草稿用,将就着看,明白个设计思路就行. 1.首先系统初始化,定 ...
- Python学习笔记——文件写入和读取
1.文件写入 #coding:utf-8 #!/usr/bin/env python 'makeTextPyhton.py -- create text file' import os ls = os ...
随机推荐
- mac ox 配置java和maven
参考http://www.cnblogs.com/iOS-mt/p/5726380.html 以及http://blog.csdn.net/done58/article/details/5113805 ...
- CentOS 6.4 x64 zabbix 2.2.2 编译安装
A. 服务端安装配置 1.下载zabbix 2.x 最新版本 http://www.zabbix.com/download.php 2.安装配置所需要软件(zabbix需要一个lamp环境) 使用 y ...
- C++数据结构之map----第一篇
摘要: 1 对于非标准类型的map,map 只需要重载小于号就可以了 2map结构初始化 map<string,double> g_lr=map<string,double>( ...
- xCode中如何安装旧的模拟器
http://blog.csdn.net/cmengzhongren/article/details/50414493 这里给出如何把老版本的SDK加入到新的Xcode中的方法.其实很简单,就是将老版 ...
- 防止多个UIAlertView重叠弹出
http://www.jianshu.com/p/7ac398ef4532 项目中可能会遇到这种情况,好几个alertView因为逻辑关系全部弹出,用户需要一个个的点击才能将所有的alertView取 ...
- MySQL常用命令总结3
id SMALLINT UNSIGNED [AUTO_INCREMENT] PRIMARY KEY, //把id定义为主键且自动排号,每张数据表只有一个主键,不能为NULL,确保记录唯一性 //省略a ...
- NSDateFormatter调整时间格式的代码
NSDateFormatter调整时间格式的代码 在开发iOS程序时,有时候需要将时间格式调整成自己希望的格式,这个时候我们可以用NSDateFormatter类来处理.例如://实例化一个NSDat ...
- 浅析IoC框架
今日拜读了一篇关于IOC的文章,特意转载,和大家分享一下 1 IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实 ...
- EF的join用法
var customers = DB.Customer.Join(DB.Commission, cst => cst.CommissionId, ...
- graphical Layout调大一点
布局最右边的放大器按钮好难找啊