쌍 문 동

导航

Python十一课--文件和流

一.打开文件

1.打开文件可以使用open函数,返回一个file object,具体用法如下

    open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

      这里的file是一个用文本字符串表示的文件名,如果文件不在当前目录下则需要给出其完整路径
     buffering控制文件的缓冲,0表示无缓冲,1表示有缓冲,-1表示使用默认缓冲区大小
    mode缺省值为r,表示对文件只做读操作,mode 为w表示写操作(不可读;不存在则创建;存在则会清空原有文件的内容)
    mode 为x表示创建一个新文件并执行写操作(不可读;文件存在会抛出异常)
    mode 为a表示追加操作(可读;不存在则创建;存在则只追加内容)注意:mode ='a'只支持追加新内容,不支持读操作。(表格有误)
其余参数的意义请参见帮助

 

2.如果需要打开文件c:\python\hello.txt,则可以:

>>> f = open(r'c:\python\hello.txt')

如果文件不存在,则会得到如下提示:
Traceback (most recent call last):
  File "<pyshell#93>", line 1, in <module>
    f = open(r'c:\python\hello.txt')
FileNotFoundError: [Errno 2] No such file or directory: 'c:\\python\\hello.txt'
3.Python对打开的是文本文件还是二进制文件(例如声音剪辑或者图像)进行区分,如果是二进制文件,则可以将参数b添加到其文件打开模式中使用
     例如,使用mode=’rb’表示读取一个二进制文件

参数+也可以用到其他任何模式中,表明读和写都是允许的,例如,r+ 模式(读,追加模式)

>>> f = open('c:\python\hello.txt','r+',encoding='utf-8')
>>> data = f.read()  # 读出文件中的内容
>>> print(data)
The aircraft has yet to actually take off, 
but the company behind Stratolaunch says 
it's expecting to perform a launch demonstration 
by "as early as 2019."
>>> f.write("test...\n")
8
>>> print(f.read())
                              # 为什么这里的输出是空的?见下

>>> f.tell()            # 获取文件光标的现有位置
170

>>> f.seek(0)                # 将文件光标挪至文件开头
0

>>> print(f.read())
The aircraft has yet to actually take off, 
but the company behind Stratolaunch says 
it's expecting to perform a launch demonstration 
by "as early as 2019."test...

 

 

 

二.文件的基本方法

1.读和写

(1.文件(或流)最重要的能力是提供或者接收数据
(2.Python只能将字符串写入到文本文件,要将数值数据存储到文本本件中,必须先用内建函数str()将其转换为字符串格式
(3.如果有一个名为f的文件对象,那么可以用f.write方法和f.read方法(以字符串形式)写入和读取数据

>>> f = open(r'c:\python\hello3.py', 'w’)

>>> f.write('Hello, ')
7                      # 返回写入的字节数
>>> f.write(‘world!’)  # 调用write方法时参数被追加到文件尾
6

>>> f.close()         # 完成操作后需要调用close方法
执行完上面语句后,你会发现原来文件中的内容被清空;如果确实是需要执行添加操作,则应将模式mode设为’a’


读取的时候告诉流需要读取多少个字符即可
>>> f = open(r'c:\python\hello3.py', 'r')
>>> f.read(5)              # 读取5个字符
'Hello'
>>> f.read()            # 读取剩余内容
', world!'
>>> f.close()
如果仅对文件内容进行读取,则无需指定打开模式,因为缺省值为r

2.管道输出

(1.:在Unix的shell中典型的管道(pipeline)输出命令形式为
     cat somefile.txt | python somescript.py
cat somefile.txt把somefile.txt的内容写到标准输出(sys.stdout)
python somecript.py 运行脚本,从标准输入中读取数据并将结果写到标准输出中
   (2. 管道符号(|)的作用是将一个命令的标准输出和下一个命令的标准输入连在一起,这样形如
        cat somefile.txt | python somescript.py
的命令会告诉somecript.py从sys.stdin中读取数据(cat somefile.txt写入的),并将结果写入sys.stdout
   (3.在Windows系统中安装cygwin(http://cygwin.com,a large collection of GNU and Open Source tools which provide functionality similar to a Linux distribution on Windows),并运行上面的命令

(4.

假设有一个脚本文件somescript.py,内容如下:
# somescript.py
import sys
text = sys.stdin.read()
words = text.split()
wordcount = len(words)
print('Word count:', wordcount)

另外还有一个文本文件somefile.txt:
Your mother was a hamster and your father smelled of elderberries.

以下是在cygwin环境中执行
        cat somefile.txt | python somescript.py
命令的结果

 

 注意:不使用管道输出

# somescript.py

f = open('c:\python\somefile.txt', 'r')
data = f.read()
words = data.split()
wordcount = len(words)
print('Word count:', wordcount)

 

 

3.随机访问
(1.除了按照从头到尾的顺序读取数据外(将文件作为流来处理),在文件中随意移动读取位置也是可以的
 (2.使用文件对象的seek和tell方法来直接访问感兴趣的部分,这种做法称为随机访问
        seek(offset[, whence])
        offset是字节(字符)数表示的偏移量
        whence默认值为0,表示偏移量从文件头开始计算(文本文件与二进制文件均适用);     

       如果是1表示相对当前位置的偏移;如果是2则表示相对文件尾的偏移(仅适用于二进制文件)


 

考虑下面这个例子
>>> f = open(r'c:\python\hello.txt', 'w')
>>> f.write('01234567890123456789')
>>> f.seek(5)             # 把当前读写位置移动到第5个字节处
>>> f.write(‘Hello, world!’) # 在当前位置写入字符串
>>> f.close()
>>> f = open(r'c:\python\hello.txt')
>>> f.read()
'01234Hello, world!89‘
* 注意:可以用help(io.IOBase.seek)查看关于seek的帮助信息

tell方法返回文件当前的读写位置
>>> f = open(r'c:\python\hello.txt')
>>> f.read(3)
'012'
>>> f.read(4)
'34He'
>>> f.tell()
7

4.对行进行读写

(1.可以使用file.readline()读取单独的一行(从当前位置开始直到换行符出现
(2.也可以使用带非负整数的参数作为可以读取的字节(或字符)的最大值,例如file.readline(5)
(3.使用file.readlines()方法则读取一个文件中所有行并将其作为列表返回,类似于fileinput.input()(返回FileInput类的对象)
  (4.writelines方法和readlines方法正好相反:传给它一个字符串的列表(实际上任何序列和可迭代对象都行),它会将所有字符串写入文件。另外,没有writeline方法,可使用write方法写入一行

>>> f = open(r'c:/python/fileinputoutput.txt', 'x')
>>> lst = ['This is the first line.', 'This is the second line.', 'And this is the third line.']
>>> f.writelines(lst)
>>> f.close()

如果指定文件不存在则创建新文件,显示结果如下:
This is the first line.This is the second line.And this is the third line.
由此看来,程序不会自己增加新行,需要自己在每行后添加换行符,用于文本文件中写入时使用的行分隔符是’\n’

 

5.关闭文件

(1.应该牢记在使用完文件后调用close()进行关闭。写入过的文件总是应该关闭,是因为Python可能会缓存写入的数据;如果程序因为某些原因崩溃了,那么数据就不会写入文件中
(2.为了确保关闭文件,可以使用try/finally语句,并且在finally中调用close方法

f = open(r'c:/python/fileinputoutput.txt‘)
try# write data to your file
finally:
       f.close()

(3.事实上有专门为这种情况设计的语句,即使用with语句管理上下文

>>> with (open(r'c:/python/fileinputout.txt')) as somefile:
    do_something(somefile)

这里with语句打开文件并将其赋值到变量somefile上,之后可以执行对文件的其它操作,操作结束后文件会自动关闭,即使是由于异常引起的结束也是如此  

在Python 2.7 后,with支持同时对多个文件的上下文进行管理,即:    
with open('log1') as obj1, open('log2') as obj2:
pass 例如, >>> with open(r'c:/python/hello.txt', encoding = 'utf-8') as f1, open(r'c:/python/hello4.txt', encoding = 'utf-8') as f4: print(f1.read()) print(f4.read())

6.基本的文件方法

(1.假设现在有一个文本文件fileinputoutput.txt,其内容为
Welcome to this file
There is nothing here except
These three lines
然后我们使用文件的各种读写方法

>>> f = open(r'c:/python/fileinputoutput.txt')
>>> f.read(7)   # 从文件当前位置读入7个字节
'Welcome'
>>> f.read(4)
' to '
>>> f.close()


>>> f = open(r'c:/python/fileinputoutput.txt')
>>> print(f.read())   # 读取文件所有内容
Welcome to this file
There is nothing here except
These three lines
还可以使用readline()来读取文件所有内容
>>> f = open(r'c:/python/fileinputoutput.txt')
>>> for i in range(3):
    print(f.readline(), end=' ')

    
Welcome to this file
There is nothing here except
These three lines


试试readlines方法,将会读取换行符
>>> import pprint
>>> pprint.pprint(open(r'c:\python\fileinputoutput.txt').readlines())
['Welcome to this file\n',
 'There is nothing here except\n',
 'These three lines']

 

7.写文件

使用write方法写入一行或多行文件内容
>>> f = open(r'c:\python\fileinputoutput.txt', 'w')
>>> f.write('This\n is\n another\nstring.')
25
>>> f.close()


使用writelines方法写入多行文件内容
>>> f = open(r'c:\python\fileinputoutput.txt', 'w’)
>>> lst = ['Welcome to this file\n', 'There is nothing here except\n', 'These three lines']
>>> f.writelines(lst)
>>> f.close()

 



三.对文件内容进行迭代

1.对文件内容进行迭代

对文件内容进行迭代以及重复执行一些操作,是最常见的文件操作之一

(1.例如可以在while循环中使用read方法,即对文件内容按字节处理

f = open(r'c:\python\fileinputoutput.txt')
while True:
    char = f.read(1)
    if not char: break
    print(char)
f.close()

 

(2.处理文本文件时还可以对文件的行进行迭代而不是处理单个字符,例如

f = open(r'c:\python\fileinputoutput.txt')
while True:
    line = f.readline()
    if not line: break
    print(line)
f.close()

2.读取文件所有内容

(1.如果文件不是很大,可以使用不带参数的read方法一次性读取整个文件
(2.或者还可以使用readlines方法,将文件读入一个字符串列表中,这时列表中每个元素就是文件中的一行
 (3.需要注意的是,当文件尺寸非常大时,使用readlines方法会占用太多的内存。这时既可以用while和readline方法的组合来替代,也可以使用for和fileinput.input方法的组合

import fileinput
>>> for line in fileinput.input(r'c:\python\fileinputoutput.txt'):
    print(line)

 

3.对行进行读取时的效率
(1.#对文件的第3行,做一个特殊的打印(这种方式比较低效,因为它会先把文件全部读取到内存中,文件较大时会对性能有很大影响)

>>> f = open('c:\python\hello.txt','r',encoding='utf-8')
>>> for index,line in enumerate(f.readlines()):
    if index == 2:
        print('-------testing line------', line)        
    print(line)

(2.#比较高效的,对文件的第3行进行特殊的打印,会一行一行去读取文件内容,不会一次性先把文件全部读取到内存中

>>> f = open('c:\python\hello.txt','r',encoding='utf-8')
>>> count = 0
>>> for line in f:
    if count == 2:
        print('-------testing line------', line)
    count += 1
    print(line)

4.文件迭代器

(1.由于文件对象是可迭代的,所以可以直接在for循环中使用它们,从而对其进行迭代

f = open(r'c:\python\fileinputoutput.txt')
for line in f:
    print(line)
f.close()

(2.需要注意的是,sys.stdin也是可迭代的

import sys
for line in sys.stdin:
    s = reversed(line)
    if line == ‘\n’: break       # 直接输入回车后跳出循环
    print(list(s))

 

>>> f = open(r'c:\python\somefile.txt', 'x')
>>> f.write('First line.\n')
12
>>> f.write('Second line.\n')
13
>>> f.write('Third line.\n')
12
>>> f.close()
>>> lines = list(open(r‘c:\python\somefile.txt’))  # 将文件内容写入列表
>>> lines
['First line.\n', 'Second line.\n', 'Third line.\n']
>>> first, second, third = open(r‘c:\python\somefile.txt’)   # 序列解包
>>> first
'First line.\n'
>>> second
'Second line.\n'
>>> third
'Third line.\n'

 

 小结:

类文件对象:类文件对象是支持read、readline、readlines、write和writelines方法的对象
打开和关闭文件:提供一个文件名,可以使用open函数打开一个文件;如果希望确保文件被正常关闭,则可以使用with语句
模式和文件类型:打开文件时可以提供模式信息,’r’代表读模式,’w’代表写模式,也可以将文件以二进制文件形式打开
读和写:使用read或是write方法可以对文件对象进行读写操作
读写行:使用readline和readlines方法可以从文件中读取行,使用writelines语句则可以写入一行或多行数据
迭代文件内容:有很多方式可以迭代文件的内容。如果是迭代文本中的行,可以通过迭代文件对象本身来完成
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
打开文件file并返回文件对象



 

posted on 2020-08-19 20:51  쌍문동  阅读(194)  评论(0编辑  收藏  举报