一、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 Python基础_文件读写 Python 第1张 Python基础_文件读写 Python 第2张 Python3实现: Python基础_文件读写 Python 第3张 Python基础_文件读写 Python 第4张 输出结果: Python基础_文件读写 Python 第5张 Python基础_文件读写 Python 第6张 这里需要注意一点就是,我们在读写文件时候,特别是在读的时候大部分情况,如果文件路径不正确或者文件不存在,也就是找不到文件,又或者是在进行文件操作时候出现I/O错误,就会报错。此时如果要保证代码的健壮性最好加上try...finally来实现错误捕捉以及及时关闭文件对象(优化代码如下): Python基础_文件读写 Python 第7张 Python基础_文件读写 Python 第8张 输出结果: Python基础_文件读写 Python 第9张 Python基础_文件读写 Python 第10张 上面关闭文件的代码有时候很容易忘记,所以我们接下来使用Python with方法来完成自动关闭文件: Python基础_文件读写 Python 第11张 Python基础_文件读写 Python 第12张 输出结果: Python基础_文件读写 Python 第13张 Python基础_文件读写 Python 第14张 可以看到在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()  

实例一:

Python基础_文件读写 Python 第15张 Python基础_文件读写 Python 第16张 输出结果: Python基础_文件读写 Python 第17张 Python基础_文件读写 Python 第18张

实例二:

Python基础_文件读写 Python 第19张 Python基础_文件读写 Python 第20张 输出结果: Python基础_文件读写 Python 第21张 Python基础_文件读写 Python 第22张 readlines()方法跟read()方法一样,都会消耗大量内存空间。

实例三:

Python基础_文件读写 Python 第23张 Python基础_文件读写 Python 第24张 或者: Python基础_文件读写 Python 第25张 Python基础_文件读写 Python 第26张 输出结果: Python基础_文件读写 Python 第27张 Python基础_文件读写 Python 第28张

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

方法一: Python基础_文件读写 Python 第29张 Python基础_文件读写 Python 第30张 方法二: Python基础_文件读写 Python 第31张 Python基础_文件读写 Python 第32张 输出结果: Python基础_文件读写 Python 第33张 Python基础_文件读写 Python 第34张

六、文件操作其他方法

方法 描述
flush() 刷新缓冲区数据,将缓冲区中的数据立刻写入文件
next() 返回文件下一行,这个方法也是file对象实例可以被当作迭代器使用的原因
truncate(size) 截取文件中指定字节数的内容,并覆盖保存到文件中,如果不指定size参数,则文件将被清空;Python2中无返回值,Python3返回新文件的内容字节数
write(str) 将字符写入文件,没有返回值
writelines(sequence) 向文件写入一个字符串货一个字符串列表,如果字符串列表中元素需要换行要自己加入换行符
fileno() 返回一个整型的文件描述符,可以用于一些底层I/O操作上(如os模块的read方法)
issatty() 判断文件是否被连接到一个虚拟终端,是则返回True,否则返回False
 
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄