Python Task07 文件与文件系统

Python Task07 文件与文件系统

  1. 文件读写

读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。
读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

1.1 读文件

要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符。
标示符’r’表示读;如果文件不存在,open()函数就会抛出一个IOError的错误,并且给出错误码和详细的信息
如果文件打开成功,则调用read()方法可以一次读取文件的全部内容,Python把内容用一个str对象表示
调用close()方法关闭文件。注意:文件使用完毕后必须关闭(因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量是有限的)
如果文件打开成功,则调用read()方法可以一次读取文件的全部内容,Python把内容用一个str对象表示
调用close()方法关闭文件。注意:文件使用完毕后必须关闭(因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量是有限的)
由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。
所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try … finally来实现
还有一种更加单的方法:Python引入了with语句来自动帮我们调用close()方法。

优势:这和前面的try … finally是一样的,但是代码更佳简洁,并且不必调用f.close()方法
三种读文件的方式

  1. read(size) 每次最多读取size个字节的内容
  2. readline() 每次读取一行的内容
  3. readlines() 读取所有内容,并按行返回list
    一般来讲,如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便
    补充
    1、file-like Object
    像open()函数返回的这种有个read()方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object不要求从特定类继承,只要写个read()方法就行。
    StringIO就是在内存中创建的file-like Object,常用作临时缓冲。

2、二进制文件
前面讲的默认都是读取文本文件,并且是UTF-8编码的文本文件。要读取二进制文件,比如图片、视频等等,用’rb’模式打开文件即可
3、字符编码
要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数,例如,读取GBK编码的文件
遇到有些编码不规范的文件,如遇到UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。此时open()函数还接收一个errors参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略
我们选择errors=‘ignore’,那么如果出现非法编码字符,会直接忽略

1.2 open() 方法总结

Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。
注意:

使用 open()方法一定要保证关闭文件对象,即调用 close()方法。
open()函数常用形式是接收两个参数:文件名(file)和模式(mode)
参数说明:

file: 必需,文件路径(相对或者绝对路径)。
mode: 可选,文件打开模式
buffering: 设置缓冲
encoding: 一般使用utf8
errors: 报错级别
newline: 区分换行符
closefd: 传入的file参数类型
opener:
其中,mode 参数有:

Python Task07 文件与文件系统
Python Task07 文件与文件系统
特别的,默认为文本模式,如果要以二进制模式打开,加上b

file 对象
file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数:

file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数:
Python Task07 文件与文件系统
Python Task07 文件与文件系统
Python Task07 文件与文件系统
1.3 写文件

写文件和读文件是一样的,区别是调用open()函数时,传入标识符’w’或者’wb’表示写文本文件或写二进制文件。

我们不断使用write写入的内容先被存放在内存中,python会在空闲时间慢慢写入,只有使用了close()方法后内存中所有内容才会被写入磁盘中——所以一不要忘记close,否则可能会导致内容部分丢失。
使用‘w’模式,新内容会覆盖原来的内容,如果需要追加内容可以使用‘a’模式写入。

为了保证每次open后,我们都关闭文件——还是要使用with语句
若要写入特定编码的文本文件,open()函数需传入encoding参数,将字符串自动转换成指定编码
以’w’模式写入文件时,如果文件已存在,会直接覆盖。如果希望追加到文件末尾?可以传入’a’以**追加(append)**模式写入。
2. 内存读写

很多时候,数据读写不一定是文件,也可以在内存中读写。
StringIO和BytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。

2.1 StringIO

顾名思义就是在内存中读写str。

一、 写入
要把str写入StringIO,我们需要先创建一个StringIO,然后像文件一样写入即可
getvalue()方法用于获得写入后的str
二、读取
读取StringIO,可以用一个str初始化StringIO,然后像读文件一样读取
2.2 BytesIO

StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO
一、写入
BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes
请注意,写入的不是str,而是经过UTF-8编码的bytes。
二、读取
StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取
3. OS 文件/目录方法

3.1 OS 模块中关于文件/目录常用的函数使用方法
有了OS(Operation System)模块,我们不需要关心什么操作系统下使用什么模块,OS模块会帮你选择正确的模块并调用。

os.getcwd() 用于返回当前工作目录
os.chdir(path) 用于改变当前工作目录到指定的路径
4. 序列化

Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块
“json模块的dumps()和loads()函数是定义得非常好的接口的典范:当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,我们又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性。” ——廖雪峰

4.1 序列化基础知识

变量从内存中变成可存储或传输的过程称之为序列化(在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等)
序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上
变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling
python用pickle模块实现序列化

pickle.dumps()可以把任意对象序列化成一个bytes,然后把bytes写入文件
可以用pickle.dump()直接把对象序列化后写入一个file-like object,这样就可以把对象写入到磁盘了
pickle.load()的方法把file-like object 中直接反序列划出对象
pickle可能有不兼容的问题,所以只能用于保存不重要的数据