Loading

Python基础_文件读写

一、I/O操作概述

I/O概述:

    I/O在计算机中时指Input/Output,也就是Stream的输入与输出。我们通常说的输入与输出其实在操作系统中都是相对于内存而言的,InputStream(输入流)是指数据从外部(网络、键盘、I/O设备)流进内存,OutputStream正好与之相反,数据从内存流出到外部。程序运行时,数据都是在哎内存中驻留,由CPU这个超级快的计算核心来执行,涉及到数据交换的地方就需要IO接口。

IO接口的提供以及高级编程语言中的IO操作的实现:

    操作系统十个通用的软件程序,其通用目的如下:
    硬件驱动、进程管理、内存管理、网络管理、安全管理、I/O管理
    操作系统屏蔽了底层硬件,向上提供通用接口。因此,操作I/O的能力是由操作系统提供的,每一种编程语言都会把操作系统提供的低级C接口封装起来供开发者使用,Python也不例外。

二、文件读写实现原理和操作步骤

1.文件读写实现原理:

    由于操作I/O的能力是由操作系统提供的,且操作系统不允许普通程序直接操作磁盘,所以读写文件时需要操作系统打开一个对象,这个对象通常被称之为文件描述符--file descriptor,简称fd,这个就是我们在程序中要操作的文件对象。
    通常高级编程语言会提供一个内置的函数,通过接收‘文件路径’、‘文件打开模式’等参数来打开一个文件对象,并返回该文件对象的文件描述符。因此通过这个函数我们就可以获取到要操作的文件对象,在Python中这个函数叫open(),在PHP中叫fopen()

2.文件读写操作步骤:

不同编程语言读写文件的操作步骤大体都一样,都分为以下几步:
    1)打开文件,获取文件描述符;
    2)操作文件描述符--读/写;
    3)关闭文件。

3.需要注意的是:

文件读写操作完成后,应该及时关闭。一方面,文件对象会占用操作系统的资源,另一方面,操作系统对同一时间能够打开的文件描述符的数量是有限的,在linux操作系统上可以通过ulimit -n来查看这个现实数量。如果不能及时关闭文件,还可能造成数据丢失,因为将数据写入文件时,操作系统不会立即把数据写入磁盘,而是先把数据放到内存缓存区异步写入磁盘。当调用close方法时,操作系统才会保证把没有写入磁盘的数据全部写入到磁盘,否则可能会丢失数据。

三、Python3中文件打开模式

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

打开文件的参数通常有:文件路径名称、mode参数(即打开模式)、编码模式...
这里需要搞清楚的就是mode参数,也就是我们使用什么模式打开一个文件:
Python3源码中时这样解释的:
Python3源码文件其实对文件的打开模式进行了详细的英文阐述,这里非常建议大家自己打开builtins.py文件自行查看,我相信研究看懂的远远比看别人写的文章描述的更加深刻。
这里只是粘贴一部分打开模式的简单描述部分:
========= ===============================================================
Character Meaning
--------- ---------------------------------------------------------------
'r'       open for reading (default)
'w'       open for writing, truncating the file first
'x'       create a new file and open it for writing
'a'       open for writing, appending to the end of the file if it exists
'b'       binary mode
't'       text mode (default)
'+'       open a disk file for updating (reading and writing)
'U'       universal newline mode (deprecated)
========= ===============================================================
接下来我们队几个常见且重要的模式进行中文解析:
打开模式
描述
r
以只读模式打开文件,并将文件指针指向文件开头;如果文件不存在则报错。
w
以只写模式打开文件,并将文件指针指向文件开头;如果文件存在则将其情况并写入,如果文件不存在则创建
a
以只追加写模式打开文件,并将文件指针指向文件末尾;如果文件不存在则创建。
r+
在r的基础上增加可写功能
w+
在w的基础上增加可读功能
a+
在a的模式上增加可读功能
b
读写二进制文件(默认是t,表示文本模式),需要与上面几种模式搭配使用,如:ab,wb,ab
x
创建一个新文件再打开它写入;如果文件已存在则报错。
思考1:r+、w+和a+都可以对文件进行读写,他们有何区别?
    会覆盖当前文件指针所在位置的字符,如原来文件内容是“Hello World”,以r+模式打开文件写入“hi”则文件内容变成“hillo World”
打开模式
详细描述
r+
会覆盖当前文件指针所在位置的字符,如原来文件内容是“Hello World”,以r+模式打开文件写入“hi”则文件内容变成“hillo World”
w+
w+在打开文件时就会先将文件内清空,再进行写入。
a+
该模式只能写在文件末尾,也就是在文件末尾进行追加写入。
思考2:为何要定义这些模式?为什么不能像word文档意义打开它之后既可读又可写还可以修改呢?
    问题答案参考网上:
    跟安全有关,有这种观点的大部分是做运维的朋友,他们认为这就像linux上的rwx(读、写、执行)权限。
    跟操作系统内核管理I/O的机制有关,有这种观点的大部分是做C开发的,特别是与内核相关的开发人员。为了提高读写速度,要写入磁盘的数据会先放进内存缓冲区,之后再回写。由于可能会同时打开很多文件,当要回写数据时,需要遍历以打开的文件判断是否需要回写。他们认为如果打开文件时指定了读写模式,那么需要回写时,只要去查找以“可写模式”打开的文件就可以了。

四、Python文件操作实例

读取文件open_test.py,该文件的字符编码为utf-8
Python3实现:
输出结果:
这里需要注意一点就是,我们在读写文件时候,特别是在读的时候大部分情况,如果文件路径不正确或者文件不存在,也就是找不到文件,又或者是在进行文件操作时候出现I/O错误,就会报错。此时如果要保证代码的健壮性最好加上try...finally来实现错误捕捉以及及时关闭文件对象(优化代码如下):
输出结果:
上面关闭文件的代码有时候很容易忘记,所以我们接下来使用Python with方法来完成自动关闭文件:
输出结果:
可以看到在with语句中文件时没有关闭的,只有出了with语句后文件会自动关闭
关于Python with上下文管理的用法可以查看文章了解: https://www.cnblogs.com/suguangti/p/11123515.html

五、Python文件读取相关方法

对文件的读取操作需要将文件中的数据加载到内存中,而在上面所用到的read()方法会一次性的把文件中所有的内容全部加载到内存中。这显然是不合理的,如果我们读取的是一个大文件,有几个G的文件时,必然会耗光机器的内存或者直接报错,所以肯定有一些其他的读取方法来解决:
 
方法
描述
read()
一次性读取文件所有内容
read(size)
每次最多读取指定长度内容,在Python2中size指定是字节长度,而在Python3中size指定为字符长度
readlines()
一次性读取文件所有内容,按行返回一个list
readline()
每次只读取一行内容
此外还有两个关于文件指针位置的方法:
方法
描述
seek()
将文件指针移动到指定字节位置
tell()
 

实例一:

输出结果:

实例二:

输出结果:
readlines()方法跟read()方法一样,都会消耗大量内存空间。

实例三:

或者:
输出结果:

解决打印每一行换行符问题:

方法一:
方法二:
输出结果:

六、文件操作其他方法

方法
描述
flush()
刷新缓冲区数据,将缓冲区中的数据立刻写入文件
next()
返回文件下一行,这个方法也是file对象实例可以被当作迭代器使用的原因
truncate(size)
截取文件中指定字节数的内容,并覆盖保存到文件中,如果不指定size参数,则文件将被清空;Python2中无返回值,Python3返回新文件的内容字节数
write(str)
将字符写入文件,没有返回值
writelines(sequence)
向文件写入一个字符串货一个字符串列表,如果字符串列表中元素需要换行要自己加入换行符
fileno()
返回一个整型的文件描述符,可以用于一些底层I/O操作上(如os模块的read方法)
issatty()
判断文件是否被连接到一个虚拟终端,是则返回True,否则返回False
 
posted @ 2020-04-19 19:09  MrSu  阅读(494)  评论(0编辑  收藏  举报