文件和流

文件和流——它们的对象和函数可以让你在程序调用时存储数据,并且可以处理来自其他程序的数据。

打开文件

open函数使用一个文件名作为唯一的强制参数,然后返回一个文件对象。模式(mode)和缓存(buffering)参数都是可选的。

文件模式

如果open函数只带一个文件名参数,那么我们可以获得能读取文件内容的文件对象。如果要向文件内写入内容,则必须提供一个模式参数来显示声明。
+参数可以用到其他任何模式中,指明读和写都是允许的。比如r+能在打开一个文本文件用来读写时使用。

描述
'r' 读模式
'w' 写模式
'a' 追加模式
'b' 二进制模式(可添加到其他模式中使用)
'+' 读/写模式(可添加到其他模式中使用)

b模式改变处理文件的方法。一般来说,Python假定处理的是文本文件(包含字符)。通常这样做是不会有任何问题的。但如果处理的是一些其他类型的文件(二进制文件),比如声音剪辑或者图像,那么应该在模式参数中增加b。参数rb可以用来读取一个二进制文件。

缓冲

open函数第三个参数(可选)控制着文件的缓冲。如果参数是0(或者是False),I/O(输入/输出)就是无缓冲的(所有读写操作都直接针对硬盘);如果是1(或者是True),I/O就是有缓冲的(意味着Python使用内存来代替硬盘),让程序更快,只有使用了flush或者close时才会更新硬盘上的数据。大于1的数字意味着缓存区的大小(单位是字节),-1(或者时任何负数)表示使用默认的缓冲区大小。

基本的文件方法

类文件对象是支持一些file类方法的对象,最重要的是支持read方法或者write方法,或者两者兼有。urllib.urlopen返回的对象是一个类文件对象。它们支持read、readline和readlines。

读和写

文件(或流)最重要的能力是提供或者接收数据。如果有一个名为f的类文件对象,那么就可以用f.write方法和f.read方法(以字符串形式)写入和读取数据。
每次调用f.write(string)时,所提供的参数string会被追加到文件中已存在部分的后面。

>>> f = open('somefile.txt', 'w')
>>> f.write('Hello, ')
>>> f.write('World!')
>>> f.close()

在完成了对一个文件的操作时,调用close。
读取很简单,只需要记得告诉流要读多少字符(字节)即可。

>>> f = open('somefile.txt', 'r')
>>> f.read(4)
'Hell '
>>> f.read()
'o. World!'

管式输出

管道符号将一个命令的标准输出和下一个命令的标准输入连在一起。

$ cat somefile.txt | python somescript.py | sort
  • cat somefile.txt:把somefile.txt的内容写到标准输出(sys.stdout)
  • python somescript.py:运行了Python脚本somescript.py。脚本应该是从标准输入读,把结果写到标准输出。
  • sort:这条命令从标准输入(sys.stdin)读取了所有的文本,按字母排序,然后把结果写入标准输出。

这样,就知道somescript.py会从它的sys.stdin中读取数据(cat somefile.txt写入的),并把结果写入它的sys.stdout(sort在此得到数据)中。

# somescript.py
import sys
text = sys.stdin.read()
words = text.split()
wordcount = len(words)
print 'Wordcount:', wordcount
Your mother was a hamster and your
father smelled of elderberries.

Wordcount:11


读写行

file.readline方法读取单独的一行。
flie.readlines方法可以读取一个文件中的所有行并将其作为列表返回。
writelines方法和readlines相反:传给他一个字符串的列表,它会把所有的字符串写入文件(或流)。注意,程序不会增加新行,需要自己添加。没有writeline只有wirte

关闭文件

关闭文件可以避免在某些操作系统或设置中进行无用的修改,这样做也会避免用完系统中所打开文件的配额。
写入过的文件总是应该关闭的,是因为Python可能会缓存(出于效率考虑, 可能会把文件临时的储存在某地)写入的数据,如果程序因为某些原因崩溃了,那么数据根本不会被写入文件。为了安全起见,要在使用完文件后关闭。
使用with语句可以解决这种关闭文件问题

with open('somefile.txt') as somefile:
      do_something(fomefile)

with语句可以打开文件并且将其赋值到变量上(本例是somefile)。之后就可以将数据写入语句体中的文件(或执行其他操作)。文件在语句结束后会被自动关闭,即使是由于异常引起的结束也是如此。

使用基本文件方法

一个简单的文本文件

Welcome to this file
There is nothing here except
This stupid haiku
>>> f = open(r'c:\text\somefile.txt')
>>> f.read(7)
'to'
>>> f.close()
>>> f = open(r'c:\text\somefile.txt')
>>> print f.read()
Welcome to this file
There is nothing here except
This stupid haiku
>>> f.close()
>>> f = open(r'c:\text\somefile.txt')
>>> for i in range(3):
            print str(i) + ':' + f.readline()
0:Welcome to this file
1:There is nothing here except
2:This stupid haiku
>>> f.close()
>>> import pprint
>>> pprint.pprint(open(r'c:\text\somefile.txt').readlines())
['Welcome to this file\n',
'There is nothing here except\n',
'This stupid haiku']
>>> f = open(r'c:\text\somefile.txt')
>>> f.write('this\nis no\nhaiku')
>>> f.close()
>>> f = open(r'c:\text\somefile.txt')
>>> lines = f.readlines()
>>> f.close()
>>> lines[1] = "isn't a\n"
>>> f = open(r'C:\text\somefile.text', 'w')
>>> f.writelines(lines)
>>> f.close()

对文件内容进行迭代

按字节处理

在while循环中使用read方法。

f = open(filename)
while True:
    line = f.readline()
    if not line: break
    process(line)

按行操作

f = open(filename)
while True:
    line = f.readline()
    if not line: break
    process(line)
f.close()

读取所有内容

如果文件不是很大,可以使用不带参数的read方法一次读取整个文件(把整个文件当做一个字符串来读取),或者使用readlines方法(把文件读入一个字符串列表,在列表中每个字符串就是一行)

使用fileinput实现懒惰行迭代

在需要对一个非常大的文件进行行迭代的操作时,readlines会占用太多的内存。这儿时候可以使用while循环和readline方法替代。


import fileinput
for line in fileinput.input(filename):
    process(line)

文件迭代器

文件对象是可迭代的,这就意味着可以直接在for循环中使用它们,从而对它们进行迭代。


f = open(filename)
for line in f:
    process(line)

只要没有向文件内写入内容,那么不关闭文件也是可以的。
···
for line in open(filename):
process(line)
···

小结

类文件对象
打开和关闭文件
模式和文件类型
标准流
读和写
读写行
迭代文件内容

推荐阅读更多精彩内容

  • .NET Framework将文件视为数据流。流是一系列用字节表示的数据分组。数据流有底层存储介质,这些存储介质通...
    CarlDonitz阅读 170评论 0 0
  • 到目前为止,我们已经使用了 iostream 标准库,它提供了 cin 和 cout 方法分别用于从标准输入读取流...
    希希爸爸阅读 68评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 87,834评论 13 122
  • 我的博客原文 Python打开文件可以用open函数语法:open(filename, mode[, buffer...
    logging_DEBUG阅读 1,096评论 0 2
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 4,766评论 4 8