Python之模块IO

时间:2023-12-19 19:37:38

Python之模块IO

io概叙

io模块提供了python用于处理各种类型I/O的主要工具,主要有三种类型的I/O:文本I/O,二进制I/O和原始I/O;这些都是通用类型,各种后备存储可使用其中的每一种类型,所以这些类型的具体对象称为文件对象。他通常的术语叫流和文件对象。

每个具体流对象都具有各种功能:可以是只读,只写或读写。它可以允许任意的随机访问;向前或向后寻找任何位置或者只允许顺序访问如套接字或管道的情况下。

所有的流都会检测提供给它的数据类型,如给二进制流str字符类型的write()的写方法将会引发一个TypeError异常。

io类层次结构

I/O流的实现被组织为类的层次结构,第一个抽象基类为ABCs,用于指定不同类别的流,然后提供标准流实现的具体类。

I/O层次结构的顶部是抽象基类IOBase,它定义了流的基本接口,但读取和写入流之间没有分离。

RawIOBase它是IOBase延伸的类,用来处理字节读取和写入流,RawIOBase的子类为机器文件系统中的文件提供接口。

BufferedIOBase类继承RawIOBase类,它的子类:BufferedWriter,BufferedReader,BufferedRWPair三个缓冲流类,实现功能为可写,可读,以及可读写。BufferedRandom子类为随机访问流提供缓冲接口,另一个子类BytesIO是内存中字节流。

TextIOBase类继承IOBase,用于处理字节表示文本流,并从字符串处理编码和解码。它的子类:TextIOWrapper是缓冲的原始流BufferedIOBase的缓冲文本接口,StringIO是文本的内存流。

总结io模块提供的类层次方法:

类名 继承 存根方法 Mixin方法和属性
IOBase fileno,seek和truncate close,closed,enterexit,flush,isatty,iternext,readable,readline,readlines,seekable,tell,writable,writelines
RawIOBaes IOBase readinto,write 继承的IOBase方法read和readall
BufferedIOBase IOBase detah,read,readl,write 继承IOBase方法readinto,readintol
TextioBase IOBase detach,read,readline,write 继承IOBase方法encoding,errors,newlines

io模块的类图

IOBase

-RawIOBase,无缓存的字节流

-+FileIO,操作系统文件流

-BufferedIOBase,缓存的字节流

-+BytesIO

-+BufferedReader

-+BufferedWriter

-+BufferedRandom

-+BufferedRWPair

-TextIOBase,编码相关的文本流

-+StringIO,文本的内存流

-+TextIOWrapper

io模块的3种I/O

原始I/O,即RawIOBase及其子类

也被称为无缓存I/O。

操作底层块,既可以用于文本I/O,也可以用于字节I/O。不推荐使用。

f = open("myfile.jpg", "rb", buffering=0)

文本I/O,即TextIOBase及其子类

读取一个str对象,得到一个str对象。

f = open("myfile.txt", "r", encoding="utf-8")

f = io.StringIO("some initial text data")

字节I/O(缓存I/O),即BufferedIOBase及其子类

也称为缓存I/O。

读取一个bytes-like对象,得到一个bytes对象。

f = open("myfile.jpg", "rb")

f = io.BytesIO(b"some initial binary data: \x00\x01")

IO基类

class io.IOBase

所有IO类的抽象基类,作用于字节流,没有公共构造函数。

它为派生类提供了许多方法,IOBase类以及其子类都支持迭代器协议。

IOBase提供的数据属性和方法:

close():冲洗并关闭此流,一旦文件关闭,对文件的任何操作都会引发一次ValueError异常

closed():如果流文件被关闭则返回True否则返回False

fileno():返回流的底层文件描述符为整数

flush():刷新流到写入缓冲区

isatty():如果流是交互式即连接到终端设备则返回True否则返回False

readable():如果可以从流中读取则返回True否则返回False

readline(size=-1):从流中读取并返回一行,如果size指定,则读取指定大小字节的数据

readlines(hint=-1):从流中读取并返回行列表,可以指定hint来控制读取的行数。

seek(offset[,whence]):将柳位置更改为给定的字节偏移量(offset),whence为偏移量指示位置,默认为SEEK_SET即0流的开始位置,必须为0或者正整数,SEEK_CUR或1为当前流位置,SEEK_END或2为流的结尾。

seekable():如果流支持随机访问则返回True否则返回false

tell():返回当前流的位置

truncate(size=None):将流大小调整为以字节为单位的给定大小(size),返回新的文件大小

writable():如果流支持写入则返回true,否则返回false

writelines():写入流列表,不提供换行符

del():销毁对象,close()方法为此方法的默认实现

class io.RawIOBase

原始二进制IO的基类,它继承IOBase,没有公共构造函数

原始二进制IO通常提供对底层操作系统设备或API的低级别访问。

除了IOBase提供的属性和方法外,RawIOBase还提供了以下方法:

read(size=-1):从对象中读取size指定大小的字节并返回,如果size未指定或为-1则返回EOF之前的所有字节,如果对象为非阻塞且没有读取字节则返回None

readall():读取并返回流中的所有字节

readinto(b):将字节读入预先分配的可写类字节对象b,并返回读取的字节数,读取 完返回None

write(b):写入给定类字节对象b,并返回写入字节的数目

class io.BufferedIOBase

支持以缓冲的二进制流的基类,它继承IOBase,没有公共构造函数。

它与RawIOBase的区别在于方法read(),readinto()和write(),都将尝试读取尽可能多的输入或者消耗所有给定的输出,会造成多次系统调用。

BufferedIOBase继承或覆盖IOBase的属性和方法:

detache():将底层原始流从缓冲区分离出来并返回,在原始流被分离后,缓冲区处于不可用状态。

文本IO

文本IO所产生的是str对象,如果后备存储本身使用的是字节组成,可以通过编码和解码数据来适应平台数据类型。

文件和内存文本流的创建方法:

import io
#文件创建文本流
f = open('myfile.txt','r',encoding='utf-8') #内存中的文本流可以使用StringIO对象来创建
f1 = io.StringIO("some initial text datal")
print(f1.getvalue()) #读取文本流信息

TextIOBase

class io.TextIOBase

文本流的基类,这个类提供了一个基于字符和行的接口流IO,没有readinto()方法,因为python的字符串是不可变的,它继承IOBase

TextIOBase继承或覆盖了IOBase的属性和方法外,还提供了以下方法和属性:

encoding:用于将流的字节解码为字符串

errors:解码器或编码器的错误设置

newlines:表示翻译的换行符或一个字符串或一个字符串元祖

buffer:基本的二进制缓冲区

detach():分离底层二进制缓冲区TextIOBase并将其返回,StringIO没有底层缓冲的概念

read():从流中读取并返回最多size大小的字符作为单个字符str

readline(size=-1):读取一行或EOF返回一个str

seek(offset[,whence]):改变流位置的偏移量

tell():返回当前的流位置

write(s):将字符串s写入流并返回写入的字符数

TextIOWrapper

class io.TextIOWrapper(buffer,encoding=None,errors=None,newline=None,line_buffering=False,write_through=False)*

一个BufferedIOBase二进制流缓冲的文本流,它继承TextIOBase

newline换行符控制行结束的处理方式

TextIOWrapper继承了TextIOBase的属性,还提供:

line_buffering:线路缓冲是否启用

from io import StringIO
output = StringIO()
output.write('First line.\n')#写入第一行
print('Second line.', file=output)#写入第二行
contents = output.getvalue()
output.close()

StringIO

class io.StringIO(initial_value='',NEWLINE='\n')

用于文本IO在内存中的流,close()调用,文本缓冲将被丢弃

缓冲区的初始化值可以通过initial_value来设置,如果启用了换行符则换行符将被编码。该流位于缓冲区的开始处。

StringIO除了继承TextIOBase的方法外,还提供了此方法:

getvalue():返回一个str包含缓冲区的全部内容,换行符被解码

二进制IO(BytesIO)

二进制IO也称为缓冲IO需要类似字节的对象并生成bytes对象,不执行编码,解码或换行,这种类型的流可以用于非文本数据,并且还需要手动控制文本数据的处理。

创建二进制流的方法:

import io

#通过文本创建二进制流可以使用‘b’的模式字符串
#f_b = open("myfile.jpg",'rb')
#通过内存创建二进制流可以使用io的BytesIO方法
f_b_m = io.BytesIO(b"some initial binary data:\x00\x01")
print(f_b_m.getvalue())

缓冲IO流为I/O设备提供了比原始IO更高级级别的接口。

字节I/O

BytesIO

class io.BytesIO([initial_bytes])

使用内存中字节缓冲区的流,它继承BufferedIOBase,close()方法别调用时,缓冲被丢弃,可选参数initial_bytes是一个类似字节的对象,他包含初始数据。

BytesIO继承和覆盖BufferedIOBase和IOBase的方法,还提供以下方法:

getbuffer():在缓冲区的内容上返回一个可读写的试图,另外改变视图将透明的更新缓冲区的内容。

import io

b = io.BytesIO(b'abcdef')
view = b.getbuffer()
view[2:4] = b'56'
print(b.getvalue()) #out
b'ab56ef'

getvalue():返回bytes包含缓冲区的全部内容

缓存I/O

BufferedReader

class io.BufferedReader(raw,buffer_size=DEFAULT_BUFFER_SIZE)

缓冲区提供对可读,顺序RawIOBase对象的更高级访问,它继承BufferedIOBase,从对象读取数据时,会从基础的原始数据流请求更大的数据,并将其保存在内存缓冲区中,缓存的数据可以直接读取返回。

BufferedReader为给定的可读原始流和buffer_size创建一个构造函数,如果buffer_size被忽略,则使用DEFAULT_BUFFER_SIZE

BufferedReader除了继承和覆盖BufferedIOBase和IOBase的方法外,还提供以下方法:

peek([size]):返回流中的字节而不推进位置,对原始流最多进行一次读取。

read([size]):读取并返回size字节,如果未给出size将直到EOF或读取调用将在非阻塞模式下阻塞。

read1(size):只在原始流上调用一次,返回size字节,否则创建一个原始流读取调用。

BufferedWriter

class io.BufferedWriter(raw,buffer_size=DEFAULT_BUFFER_SIZE)

提供对可写入,顺序RawIOBase对象的更高级别访问的缓冲区,它继承BufferedIOBase,写入对象时,通常将数据放入内部缓冲区中,缓冲区将RawIOBase在各种条件下写入到底层对象,包括flush()被调用,seek()被请求时,当ufferedWriter被关闭时.

ufferedWriter为给定的可写raw原始流创建一个构造函数,如果没有给出buffer_size则默认为DEFAULT_BUFFER_SIZE

ufferedWriter继承和覆盖BufferedIOBase和IOBase的方法外,还提供了以下方法:

flush():强制缓冲区中字节流保存到原始流

write(b):写入字节对象b并返回写入的字节数\

BufferedRandom

class io.BufferedRandom(raw,buffer_size=DEFAULT_BUFFER_SIZE)

随机访问流的缓冲接口,它继承BufferedReader和BufferedWriter进一步的支持seek()和tell()功能.

BufferedRandom为第一个参数中给出的可搜索原始流创建一个读取器和写入器的构造函数,如果没有给出buffer_size则默认为DEFAULT_BUFFER_SIZE

BufferedRandom继承了BufferedReader和BufferedWriter的所有属性和方法

BufferedRWPair

class io.BufferedRWPair(reader,writer,buffer_size=DEFAULT_BUFFER_SIZE)

一个缓冲IO对象,将两个单向RawIOBase对象(一个可读,一个可写)组合为单个双向端点,它继承BufferedIOBase

reader为可读对象;writer为可写对象.

BufferedRWPair继承了BufferedIOBase的所有方法,除了detach()

原始IO

原始IO也称为无缓冲IO通常用作二进制和文本流的低级构建块,可从用户代码直接操作原始流,也可以通过在缓冲禁用的情况下以二进制模式打开文件来创建原始流:

import io
f_raw = open("54.jpg",'rb',buffering=0) #buffering选项设置为0禁止缓冲使用
print(type(f_raw)) #class '_io.FileIO'是一个IO类对象

class io.FileIO(name,mode='r',closefd=True,opener=None)

FileIO表示包含字节数据的OS级文件,它实现了RawIOBase接口和IOBase接口

name:可以值有两种选择,bytes表示将要打开的文件的路径的字符串或对象,但closefd必须是true,否则会引发异常;另一种为一个整数,表示生成的FileIO对象将访问的现有OS级文件描述符的编号。

mode:可以为'r','w','x'或'a',如果文件在打开或写入是不存在则会被创建,它会在被写入时截断。

它继承IOBase和RawIOBase的属性和方法,FileIO还提供了以下数据属性:

mode  :在构造函数中给出的模式

name  :文件名称,这是在构造函数中没有给出名称事该文件的文件描述符。