\qquad
IO
在计算机中指
Input/Output
,也就是输入和输出。
一、File(文件) 读写方法
\qquad 读写文件是最常见的IO
操作。读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
1.1 文件打开与关闭
1.1.1 File open() 方法
\qquad 要以读文件的模式打开一个文件对象,使用Python
的内置函数open()
打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出IOError
。
\qquad open()
函数常用形式是接收两个参数:文件名(file
)和模式(mode
)。
open(file, mode='r')
\qquad 完整的语法格式为:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
- 参数说明:
file
:必选参数,文件路径(相对或者绝对路径)。mode
:可选参数,用于指定文件的打开模式,默认为。buffering
:可选参数,用于指定对文件做读写操作时,是否使用缓冲区。
\qquad 如果buffing
参数的值为0
(或者False
),则表示在打开指定文件时不使用缓冲区;如果buffing
参数值为大于 1
的整数,该整数用于指定缓冲区的大小(单位是字节);如果buffing
参数的值为负数
,则代表使用默认的缓冲区大小。encoding
:打开文件时所使用的编码格式,一般使用utf8
。errors
:表示如果遇到编码错误后如何处理,最简单的方式是直接忽略:errors='ignore'
。newline
:参数newline
是用来控制在文本模式之下,一行的结束字符,可以是None,’’,\n,\r,\r\n
等。closefd
:传入的file
参数类型,缺省为True
。
\qquadTrue
:传入的file
参数为文件的文件名。
\qquadFalse
:传入的file
参数只能是文件描述符。opener
:设置自定义开启器,即自定义打开文件方式。开启器的返回值必须是一个打开的文件描述符。
mode
参数可选项如下:
模式 | 描述 | 注意事项 |
---|---|---|
r | 以只读 方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
操作的文件必须存在。 |
r+ | 打开一个文件用于读写 。文件指针将会放在文件的开头。 |
操作的文件必须存在。 |
rb | 以二进制格式 打开一个文件用于只读 。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
操作的文件必须存在。 |
rb+ | 以二进制格式 打开一个文件用于读写 。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
操作的文件必须存在。 |
w | 以只写 模式打开文件。 |
如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写 。 |
如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式 、只写 模式打开文件,一般用于非文本文件(如音频文件)。 |
如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
wb+ | 以二进制格式 、读写 模式打开文件,一般用于非文本文件(如音频文件)。 |
如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加 ,不可读。 |
如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式 打开一个文件用于追加 ,不可读。 |
如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写 。 |
如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加 ,对文件具有读写 权限。 |
如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件用于读写。 |
t | 以文本格式打开文件(默认)。 t 是 windows 平台特有的所谓text mode (文本模式),区别在于会自动识别 windows 平台的换行符。 |
类 Unix 平台的换行符是\n,而 windows 平台用的是 \r\n 两个 ASCII 字符来表示换行,python 内部采用的是 \n 来表示换行符。rt 模式下,python 在读取文本时会自动把 \r\n 转换成 \n;wt 模式下,Python 写文件时会用 \r\n 来表示换行。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 | |
b | 二进制模式。 | |
+ | 打开一个文件进行更新(可读可写)。 |
1.1.2 File 对象属性
\qquad 一个文件被打开后,会得到一个file
对象,可以调用file
对象本身拥有的属性获取当前文件的相关信息:
file.name
:返回文件的名称。file.mode
:返回打开文件时,采用的文件打开模式。file.encoding
:返回打开文件时使用的编码格式。file.closed
:判断文件是否己经关闭。
1.1.3 File close() 方法
\qquad close()
方法用于关闭一个已经打开的文件。关闭后的文件不能再进行读写操作, 否则会触发ValueError
错误。close()
方法允许调用多次。当file
对象,被引用到操作另外一个文件时,Python
会自动关闭之前的file
对象。 使用close()
方法关闭文件是一个好的习惯。close()
方法语法如下:
fileObject.close()
\qquad 由于文件读写时都有可能产生IOError
,一旦出错,后面的fileObject.close()
就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally
来实现:
try:
f = open(file, mode='r')
print(f.read())
finally:
if f:
f.close()
\qquad 但是每次都这么写实在太繁琐,所以,Python
引入了with
语句来自动帮我们调用close()
方法:
with open(file, mode='r') as f:
print(f.read())
1.2 文件读取与写入
1.2.1 文件读取
1. File read([size]) 方法
\qquad read()
方法用于从文件读取指定的字节数,如果未给定或为负则读取所有。像open()
函数返回的这种具有read()
方法的对象,在Python
中统称为file-like Object
。read()
方法语法如下:
fileObject.read([size]); # size为从文件中读取的字节数,默认为-1,表示读取整个文件。
2. File readline() 方法
\qquad readline()
方法用于从文件读取整行,包括"\n
“字符。如果指定了一个非负数的参数,则返回指定大小的字节数,包括”\n
"字符。readline()
方法语法如下:
fileObject.readline(size); # size为从文件中读取的字节数,不写size表示读取一行
3. File readlines() 方法
\qquad readlines()
方法用于读取所有行(直到结束符EOF
)并返回列表,该列表可以由Python
的for ... in ...
结构进行处理。 如果碰到结束符EOF
则返回空字符串。EOF
是一个计算机术语,为End Of File
的缩写,在操作系统中表示资料源无更多的资料可读取。 readlines()
方法语法如下:
fileObject.readlines(); # 返回一个列表,列表的每一项即为文件的每一行
1.2.2 文件写入
1. File write() 方法
\qquad write()
方法用于向文件中写入指定字符串。在文件关闭前或缓冲区刷新前,字符串内容存储在缓冲区中,这时你在文件中是看不到写入的内容的。如果文件打开模式带b
,那写入文件内容时,str
(参数)要用encode
方法转为bytes
形式,否则报错:TypeError: a bytes-like object is required, not 'str'
。write()
方法语法如下:
fileObject.write([str]) # str为要写入文件的字符串,返回写入的字符长度
2. File writelines(sequence) 方法
\qquad writelines()
方法用于向文件中写入一序列的字符串,这一序列字符串可以是由可迭代对象(例如:字符串、列表、元组、字典、集合等等)
产生的,如一个字符串列表,换行需要在换行位置写入换行符\n
。writelines()
方法语法如下:
fileObject.writelines([str])
实例:
fo = open("test.txt", "w+")
print ("文件名为: ", fo.name)
seq = ["文件写入writelines 1\n", "文件写入writelines 2\n","文件写入writelines 3\n",
"文件写入writelines 4\n","文件写入writelines 5\n","文件写入writelines 6"]
fo.writelines(seq)
fo.close()
3. File flush() 方法
\qquad flush()
方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要被动的等待输出缓冲区写入。一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用flush()
方法。flush()
方法语法如下:
fileObject.flush();
4. with 语句
\qquad 当我们写文件时,操作系统通常不会立刻将数据写入磁盘,而是在内存中进行缓存,待空闲的时候再进行写入操作。只有当调用close()
方法时,操作系统才会将没有写入的数据全部写入磁盘。如果没有调用close()
可能会导致只有一部分数据写入磁盘。所以,我们可以使用with
语句来自动调用close()
:
with open(file, mode='w') as f:
f.write('Hello, world!')
1.3 文件其他操作
\qquad file
对象提供了一些方法可以让我们更加方便的对文件进行操作,我将在本节对这些方法进行介绍。
1.3.1 File fileno() 方法
\qquad fileno()
方法返回一个整型的文件描述符(file descriptor
),可用于底层操作系统的I/O
操作。fileno()
方法语法如下:
fileObject.fileno();
1.3.2 File isatty() 方法
\qquad isatty()
方法检测文件是否连接到一个终端设备,如果是返回True
,否则返回False
。isatty()
方法语法如下:
fileObject.isatty();
1.3.3 File tell() 方法
\qquad tell()
方法返回文件的当前位置,即文件指针当前位置。tell()
方法语法如下:
fileObject.tell()
1.3.4 File seek(offset[, whence]) 方法
\qquad seek(offset[, whence])
方法用于移动文件读取指针到指定位置。seek()
方法语法如下:
fileObject.seek(offset[, whence]) # 如果操作成功,则返回新的文件位置,如果操作失败,则函数返回 -1。
- offset:开始的偏移量,也就是代表需要移动偏移的字节数,如果是负数表示从倒数第几位开始。
- whence:可选,默认值为 0。给 offset 定义一个参数,表示要从哪个位置开始偏移;0 代表从文件开头开始算起,1 代表从当前位置开始算起,2 代表从文件末尾算起。
1.3.5 File truncate() 方法
\qquad truncate()
方法用于从文件的首行首字节开始截断,截断文件为size
个字节,无size
表示从当前位置截断;size
长度后面的所有字节会被删除,其中Windows
系统下的换行代表2个字节大小。
二、StringIO 和 BytesIO
\qquad 说起IO
,很多人首先想到的是磁盘中的文件,将磁盘中的文件读取
到内存以及将内存内容写入
到文件。但是还有一种在内存中进行读写的IO
,叫类文件对象
,这一章我们就一起来学习下python
中的两个类文件对象:StringIO
和 BytesIO
。
2.1 StringIO 类文件对象
\qquad StringIO
类文件对象是用来读写字符串的。要把str
写入StringIO
,我们需要先创建一个StringIO
,然后,像文件一样进行写入即可。示例:
from io import StringIO
f = StringIO()
f.write('hello')
f.write(' ')
f.write('world!')
print(f.getvalue()) # getvalue()方法用于获得写入后的str
\qquad 内存中的对象有一个标志位
的概念,向内存中写入,标志位
会后移到下一个空白处。而读取数据的时候则是从标志位
开始读取,所以想要读取位于当前标志位
前面的数据,需要手动将标志位向前移动。
\qquad 获取全部内存内容的方法getvalue()
不受标志位
影响。
2.2 BytesIO 类文件对象
\qquad StringIO
类文件对象是用来读写二进制数据的,例如:图片、视频。要把二进制数据写入BytesIO
,我们需要先创建一个BytesIO
,然后,像文件一样进行写入即可。示例:
from io import BytesIO
b = BytesIO()
b.write('中文'.encode('utf-8')) # 经过UTF-8编码的bytes
b.getvalue()
三、OS 库
\qquad os
库提供了与操作系统相关的标准库,用来处理文件和目录。使用os
库之前需要进行导入:import os
。
3.1 OS 库常用属性
os.sep
:输出操作系统特定的路径分隔符
。windows下为"\
";Linux下为"/
"。os.pathsep
:输出用于分割文件路径的字符串。windows下为;
;Linux下为:
。os.name
:输出字符串指示当前使用平台。windows下为’nt
’;Linux下为’posix
’。os.linesep
:输出当前平台使用的行终止符。windows下为"\r\n
";Linux下为"\n
"。os.curdir
:返回当前目录: (‘.’)os.pardir
:获取当前目录的父目录字符串名:(‘..’)os.environ
:获取有关系统的各种信息,返回字典,使用os.environ.keys()
返回主目录下所有的key
,通过os.environ.get(key)
或os.environ[key]
可以取出值。Linux
常用如下:os.environ['USER']
:当前使用用户。os.environ['SHELL']
:使用shell的类型。os.environ['LANG']
:使用的语言。os.environ['SSH_AUTH_SOCK']
:ssh的执行路径。
3.2 OS 库常用方法
1. os.path 模块
os.path
模块主要用于获取文件的属性。常用方法如下:
os.path.abspath(path)
:返回path
的绝对路径。os.path.basename(path)
:返回path
最后的文件名,即os.path.split(path)
的第二个元素。如果path以/
或\
结尾,那么就会返回空值。os.path.commonprefix(list)
:返回list
(多个路径)中,所有path
共有的最长的路径。
os.path.dirname(path)
:返回path
的目录,即os.path.split(path)
的第一个元素。os.path.exists(path)
:如果path
存在,返回True
;如果path
不存在,返回False
。os.path.expanduser(path)
:把path
中包含的~
和~user
转换成用户目录。
os.path.expandvars(path)
:将给定路径中形式为$name
或${name}
的子字符串替换为环境变量name
的值。如果给定路径包含格式错误的环境变量名称或不存在的环境变量,则os.path.expandvars()
方法将保持不变。
os.path.getatime(path)
:返回path
所指向的文件或者目录的最后访问时间。os.path.getmtime(path)
:返回path
所指向的文件或者目录的最后修改时间。os.path.getctime(path)
:返回path
所指向的文件或者目录的创建时间。os.path.getsize(path)
:返回path
所指向的文件大小,以字节为单位,如果文件不存在就返回错误。os.path.isabs(path)
:判断path
是否为绝对路径,如果是则返回True
,否则返回False
。os.path.isfile(path)
:判断path
是否为文件,如果是则返回True
,否则返回False
。os.path.isdir(path)
:判断path
是否为目录,如果是则返回True
,否则返回False
。os.path.islink(path)
:判断path
路径是否为符号链接(软链接)的目录条目(类似Windows
系统中的快捷方式),如果是则返回True
,否则返回False
。
os.path.ismount(path)
:判断path
路径是否为挂载点(通过df -h
指令可以查看所有挂载点),如果是则返回True
,否则返回False
。
os.path.join(path1[, path2[,…]])
:将多个路径组合后返回,会从第一个以”/
”开头的参数开始拼接,之前的参数全部丢弃。如果有一个路径是绝对路径,则在它之前的所有参数均会被舍弃。os.path.normcase(path)
:用于规范指定路径名的大小写与斜杠。在Windows
上,此方法将指定路径中的所有字符都转换为小写,并将正斜杠(’/
’)转换为反斜杠(’\
’)。在Windows
以外的其他操作系统上,此方法返回的指定路径不变。os.path.normpath(path)
:用于规范化指定的path
路径。在路径规范化过程中,所有冗余分隔符和up-level引用均折叠。os.path.realpath(path)
:返回path
的真实路径。os.path.relpath(path[, start])
:从start
开始计算相对路径。os.path.samefile(path1, path2)
:判断path1
和path2
两个路径名是否引用相同的文件或目录。os.path.sameopenfile(fp1, fp2)
:判断fp1
和fp2
是否指向同一文件。os.path.samestat(stat1, stat2)
:用于检查给定的stat
元组是否引用相同的文件。os.path.split(path)
:把path
路径分割成目录和文件名,返回一个元组。os.path.splitdrive(path)
:一般用在windows
下,返回驱动器名和路径组成的元组。os.path.splitext(path)
:分割路径中的文件名与拓展名。
os.path.splitunc(path)
:把路径分割为加载点与文件。os.path.supports_unicode_filenames
:设置是否支持unicode
路径名。os.path.walk(path, visit, arg)
:遍历path
,进入每个目录都调用visit
函数,visit
函数必须有 3 3 3 个参数(arg, dirname, names)
,dirname
表示当前目录的目录名,names
代表当前目录下的所有文件名,args
则为walk
的第三个参数。
2. os 目录操作
os.chdir(path)
:用于切换当前工作目录到新路径path
。os.fchdir(fd)
:通过文件描述符fd
改变当前工作目录。os.chroot(path)
:用于更改当前进程的根目录为指定的目录path
,使用该函数需要管理员权限。os.getcwd()
:返回当前工作目录。os.getcwdb()
:返回一个当前工作目录的Unicode
对象。os.makedirs(path[, mode, exist_ok])
:用于递归创建目录,mode
表示权限模式。如果exist_ok
是False
(默认),当目标目录(即要创建的目录)已经存在,会抛出一个OSError
。
os.mkdir(‘dirname’)
:生成单级目录,相当于shell
中mkdir dirname
。os.pardir()
:获取当前目录的父目录(上一级目录),以字符串形式显示目录名。os.removedirs(‘dirname’)
:若dirname
目录为空,则删除,并递归到上一级目录,若为空,则删除,依此类推。os.rmdir(‘dirname’)
:删除单级空目录,如果目录非空,则抛出一个OSError
异常,相当于shell
中rmdir dirname
。os.rename(src, dst)
:用于命名文件或目录,从src
到dst
,如果dst
是一个存在的目录,将抛出OSError
。os.renames(old, new)
:递归地对目录进行更名,也可以对文件进行更名。
os.listdir(‘dirname’)
:列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印。
3. os 文件操作
os.open(file, flags[, mode])
:打开一个文件,并且设置需要的打开选项flags
,mode
参数是可选的,返回新打开文件的描述符。os.remove(path)
:删除路径为path
的文件,如果path
是一个文件夹,将抛出OSError
。os.utime(path, times)
:返回指定的path
文件的访问和修改的时间。os.unlink(path)
:删除文件路径。os.write(fd, str)
:写入字符串到文件描述符fd
中,返回实际写入的字符串长度。os.symlink(src, dst)
:用于创建一个软链接,src
源地址,dst
目标地址。