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'

StringIOBytesIO是在内存中操作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的更多相关文章

  1. python学习9—文件基本操作与高级操作

    python学习9—文件基本操作与高级操作 1. 文件基本操作 打开文件,获得文件句柄:f = open('filename',encoding='utf-8'),open会查询操作系统的编码方式,并 ...

  2. python学习总结---文件操作

    # 文件操作 ### 目录管理(os) - 示例 ```python # 执行系统命令 # 清屏 # os.system('cls') # 调出计算器 # os.system('calc') # 查看 ...

  3. [Python学习笔记]文件的读取写入

    文件与文件路径 路径合成 os.path.join() 在Windows上,路径中以倒斜杠作为文件夹之间的分隔符,Linux或OS X中则是正斜杠.如果想要程序正确运行于所有操作系统上,就必须要处理这 ...

  4. Python学习_06_文件、IO

    文件对象 python中的文件操作和c语言比较类似,包括一些缓冲.偏移量的方式. 文件对象可以通过open().file()两个内建方法创建,两个方法并没有什么不同,使用方法和c语言中的fopen() ...

  5. python学习笔记:文件操作和集合(转)

    转自:http://www.nnzhp.cn/article/16/ 这篇博客来说一下python对文件的操作. 对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句 ...

  6. python学习——大文件分割与合并

    在平常的生活中,我们会遇到下面这样的情况: 你下载了一个比较大型的游戏(假设有10G),现在想跟你的同学一起玩,你需要把这个游戏拷贝给他. 然后现在有一个问题是文件太大(我们不考虑你有移动硬盘什么的情 ...

  7. python学习8 文件的操作

    本文拷贝了on testing 的<python之文件操作:文件的读写>,只做学习之用 python的文件读写通过 一.用open函数 二.对文件读写操作 三.读取文件位置定位 1. op ...

  8. Python学习——实现文件交互的学生管理系统

    第一次用写博客,从前一直在博客园上学习,现在也来这里分享一下我的学习成果. 就开门见山的说吧.首先做了一个流程图,可能也不符合啥规范,就当草稿用,将就着看,明白个设计思路就行. 1.首先系统初始化,定 ...

  9. Python学习笔记——文件写入和读取

    1.文件写入 #coding:utf-8 #!/usr/bin/env python 'makeTextPyhton.py -- create text file' import os ls = os ...

随机推荐

  1. tooltip 鼠标移动上去出现图片或文字与title大同小异

    代码如下: <script type="text/javascript" src="jquery-1.3.2.min.js"></script ...

  2. windows下egret环境搭建

    作者:zccst 2,下载安装WebStorm(经了解是西欧捷克开发的,欧洲人对审美不够,所以界面不太好看,但是功能很强大) (1)遇到的问题是注册码问题,不过也很容易在网上找到. (2)如何打开已创 ...

  3. iOS navigationBar 的isTranslucent属性

    苹果文档: A Boolean value indicating whether the navigation bar is translucent (YES) or not (NO). The de ...

  4. Unity3D中的函数方法及解释

    一.刷新函数 Update 当MonoBehaviour启用时,其Update在每一帧被调用. LateUpdate 当Behaviour启用时,其LateUpdate在每一帧被调用. FixedUp ...

  5. JS中Exception处理

    程序开发中,编程人员经常要面对的是如何编写代码来响应错误事件的发生,即例外处理(exception handlers).如果例外处理代码设计得周全,那么最终呈现给用户的就将是一个友好的界面.否则,就会 ...

  6. HDU 5624 KK's Reconstruction

    这题目测是数据水了.我这种暴力写法显然是可以卡超时的. 假设有2000个点,15000条边,前面10000条不能构成树,后面5000条可以,这种数据显然可以卡超时. #include <stdi ...

  7. pho

    PDO(PHP Data Object) 是PHP 5新出来的东西,在PHP 6都要出来的时候,PHP 6只默认使用PDO来处理数据库,将把所有的数据库扩展移到了PECL,那么默认就是没有了我们喜爱的 ...

  8. ARM交叉编译工具链分类说明

    转载整理自:http://www.veryarm.com/cross-tools 从授权上,ARM交叉编译工具链分为免费授权版和付费授权版. 免费版目前有三大主流工具商提供,第一是GNU(提供源码,自 ...

  9. async & await 的用法

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们 编程埋下了一些 ...

  10. UVa 11747 - Heavy Cycle Edges

    题目大意:计算最小生成树有两种算法:一种是kruskal算法,另一种是与之相反的:如果图中存在环,去掉权重最大的边,直到不存在环.输出去掉的那些边. 可以用kruskal算法解决,在判断一条边时如果加 ...