15.2. io — 处理流的核心工具 — Python 文档
15.2. io — 处理流的核心工具
2.6 版中的新功能。
io 模块提供了流处理的 Python 接口。 在 Python 2.x 下,它被提议作为内置 file 对象的替代方案,但在 Python 3.x 中它是访问文件和流的默认接口。
笔记
由于该模块主要是为 Python 3.x 设计的,因此您必须注意,本文档中所有“字节”的使用都是指 str 类型(其中 bytes 是一个别名),所有“文本”的使用都是指 unicode 类型。 此外,这两种类型在 io API 中不可互换。
I/O 层次结构的顶部是抽象基类 IOBase。 它定义了流的基本接口。 但是请注意,读取和写入流之间没有分离; 如果实现不支持给定的操作,则允许它们引发 IOError。
扩展 IOBase 是 RawIOBase,它只处理原始字节到流的读取和写入。 FileIO 子类 RawIOBase 为机器文件系统中的文件提供接口。
BufferedIOBase 处理对原始字节流 (RawIOBase) 的缓冲。 它的子类 BufferedWriter、BufferedReader 和 BufferedRWPair 是可读、可写、可读可写的缓冲流。 BufferedRandom 为随机访问流提供缓冲接口。 BytesIO 是一个简单的内存字节流。
另一个 IOBase 子类 TextIOBase 处理字节表示文本的流,并处理 unicode 字符串的编码和解码。 TextIOWrapper,它扩展了它,是一个缓冲的原始流(BufferedIOBase)的缓冲文本接口。 最后,StringIO 是 unicode 文本的内存流。
参数名称不是规范的一部分,只有 open() 的参数旨在用作关键字参数。
15.2.1. 模块接口
- io.open(file, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True)
打开 file 并返回相应的流。 如果无法打开文件,则会引发
IOError。file 是一个字符串,给出要打开的文件的路径名(绝对或相对于当前工作目录)或要包装的文件的整数文件描述符。 (如果给出了文件描述符,则在返回的 I/O 对象关闭时它也将关闭,除非 closefd 设置为
False。)mode 是一个可选字符串,用于指定打开文件的模式。 默认为
'r',表示以文本模式打开阅读。 其他常见的值是'w'用于写入(如果文件已经存在则截断文件)和'a'用于追加(在 some Unix 系统上,意味着 all 将追加写入文件末尾,而不管当前查找位置如何)。 在文本模式下,如果未指定 encoding,则使用的编码取决于平台。 (对于读取和写入原始字节,请使用二进制模式并保留 encoding 未指定。)可用模式有:特点
意义
'r'开放阅读(默认)
'w'打开写入,先截断文件
'a'打开以进行写入,如果存在则附加到文件末尾
'b'二进制模式
't'文本模式(默认)
'+'打开磁盘文件进行更新(读写)
'U'通用换行模式(为了向后兼容;不应在新代码中使用)
默认模式是
'rt'(打开阅读文本)。 对于二进制随机访问,模式'w+b'打开并将文件截断为 0 字节,而'r+b'打开文件而不截断。Python 区分以二进制和文本模式打开的文件,即使底层操作系统没有。 以二进制模式打开的文件(包括 mode 参数中的
'b')将内容作为bytes对象返回,无需任何解码。 在文本模式下(默认情况下,或者当't'包含在 mode 参数中时),文件的内容作为 unicode 字符串返回,字节已被首先使用依赖于平台的编码或使用指定的 编码 (如果给定)进行解码。buffering 是一个可选整数,用于设置缓冲策略。 传递 0 以关闭缓冲(仅在二进制模式下允许),1 以选择行缓冲(仅可用于文本模式),以及一个大于 1 的整数以指示固定大小块缓冲区的大小。 当没有给出 buffering 参数时,默认缓冲策略的工作方式如下:
二进制文件以固定大小的块缓冲; 缓冲区的大小是使用试探法来选择的,尝试确定底层设备的“块大小”并回退到 DEFAULT_BUFFER_SIZE。 在许多系统上,缓冲区通常为 4096 或 8192 字节长。
“交互式”文本文件(
isatty()返回 True 的文件)使用行缓冲。 其他文本文件使用上述针对二进制文件的策略。
encoding 是用于解码或编码文件的编码名称。 这应该只在文本模式下使用。 默认编码取决于平台(无论 locale.getpreferredencoding() 返回什么),但可以使用 Python 支持的任何编码。 有关支持的编码列表,请参阅 codecs 模块。
errors 是一个可选字符串,指定如何处理编码和解码错误——这不能在二进制模式下使用。 如果存在编码错误,则通过
'strict'引发ValueError异常(默认None具有相同效果),或通过'ignore'忽略错误. (请注意,忽略编码错误会导致数据丢失。)'replace'会导致替换标记(例如'?')插入到格式错误的数据处。 写入时,可以使用'xmlcharrefreplace'(替换为适当的 XML 字符引用)或'backslashreplace'(替换为反斜杠转义序列)。 任何其他已用 codecs.register_error() 注册的错误处理名称也是有效的。newline 控制 universal newlines 如何工作(它只适用于文本模式)。 它可以是
None、、'\n'、'\r'和'\r\n'。 它的工作原理如下:在输入时,如果 newline 是
None,则启用通用换行模式。 输入中的行可以以'\n'、'\r'或'\r\n'结尾,这些在返回给调用者之前会被转换为'\n'。 如果是,则启用通用换行符模式,但行尾未翻译返回给调用者。 如果它具有任何其他合法值,则输入行仅由给定的字符串终止,并且行尾未翻译地返回给调用者。在输出时,如果 newline 是
None,则写入的任何'\n'字符都将转换为系统默认行分隔符 os.linesep。 如果 newline 是,则不会发生转换。 如果 newline 是任何其他合法值,则写入的任何'\n'字符都将转换为给定的字符串。
如果 closefd 是
False并且给出了文件描述符而不是文件名,则在文件关闭时底层文件描述符将保持打开状态。 如果给定文件名 closefd 没有效果,并且必须是True(默认值)。open() 函数返回的文件对象类型取决于模式。 当使用 open() 以文本模式打开文件时(
'w'、'r'、'wt'、'rt'等) .),它返回 TextIOBase 的子类(特别是 TextIOWrapper)。 当用于以带缓冲的二进制模式打开文件时,返回的类是 BufferedIOBase 的子类。 确切的类有所不同:在读取二进制模式下,它返回一个 BufferedReader; 在写二进制和追加二进制模式下,它返回一个 BufferedWriter,在读/写模式下,它返回一个 BufferedRandom。 禁用缓冲时,将返回原始流,即 RawIOBase、FileIO 的子类。也可以使用 unicode 或
bytes字符串作为文件进行读写。 对于 unicode 字符串 StringIO 可以像以文本模式打开的文件一样使用,对于bytes可以像打开文件一样使用 BytesIO在二进制模式。
- exception io.BlockingIOError
在非阻塞流上发生阻塞时引发错误。 它继承了
IOError。除了
IOError的那些,BlockingIOError 还有一个属性:- characters_written
一个整数,包含在阻塞之前写入流的字符数。
- exception io.UnsupportedOperation
- 继承
IOError和ValueError的异常,在对流调用不受支持的操作时引发。
15.2.2. I/O 基类
- class io.IOBase
所有 I/O 类的抽象基类,作用于字节流。 没有公共构造函数。
此类为派生类可以有选择地覆盖的许多方法提供空的抽象实现; 默认实现表示无法读取、写入或搜索的文件。
即使 IOBase 没有声明
read()、readinto()或write(),因为它们的签名会有所不同,但实现和客户端应该将这些方法视为接口的一部分. 此外,当调用它们不支持的操作时,实现可能会引发IOError。用于从文件读取或写入文件的二进制数据的基本类型是
bytes(也称为 str)。 方法参数也可以是字节数组的 bytearray 或 memoryview。 在某些情况下,例如 readinto(),需要一个可写对象,例如 bytearray。 文本 I/O 类使用 unicode 数据。2.7 版更改: 实现应支持 memoryview 参数。
请注意,在关闭的流上调用任何方法(甚至查询)都是未定义的。 在这种情况下,实现可能会引发
IOError。IOBase(及其子类)支持迭代器协议,这意味着 IOBase 对象可以迭代产生流中的行。 根据流是二进制流(产生
bytes)还是文本流(产生 unicode 字符串),行的定义略有不同。 请参阅下面的 readline()。IOBase 也是一个上下文管理器,因此支持 with 语句。 在这个例子中,file 在 with 语句的套件完成后关闭——即使发生异常:
with io.open('spam.txt', 'w') as file: file.write(u'Spam and eggs!')IOBase 提供了这些数据属性和方法:
- close()
冲洗并关闭此流。 如果文件已经关闭,则此方法无效。 一旦文件关闭,对文件的任何操作(例如 读或写)将引发
ValueError。为方便起见,允许多次调用此方法; 但是,只有第一个调用会产生效果。
- closed
如果流已关闭,则为真。
- fileno()
如果存在,则返回流的底层文件描述符(整数)。 如果 IO 对象不使用文件描述符,则会引发
IOError。
- flush()
如果适用,刷新流的写入缓冲区。 这对只读和非阻塞流没有任何作用。
- isatty()
如果流是交互式的(即连接到终端/tty 设备),则返回
True。
- readable()
如果可以读取流,则返回
True。 如果False,read()将提升IOError。
- readline(limit=- 1)
从流中读取并返回一行。 如果指定了 limit,则最多读取 limit 个字节。
二进制文件的行终止符总是
b'\n'; 对于文本文件,open() 的 newline 参数可用于选择识别的行终止符。
- readlines(hint=- 1)
从流中读取并返回行列表。 可以指定 hint 来控制读取的行数:如果到目前为止所有行的总大小(以字节/字符为单位)超过 hint,则不再读取行。
请注意,已经可以使用
for line in file: ...迭代文件对象而不调用file.readlines()。
- seek(offset, whence=SEEK_SET)
将流位置更改为给定字节 offset。 offset 相对于 wherece 指示的位置进行解释。 whence 的默认值为
SEEK_SET。 whence 的值是:SEEK_SET或0– 流的开始(默认); offset 应为零或正SEEK_CUR或1– 当前流位置; offset 可能为负SEEK_END或2– 流结束; offset 通常为负
返回新的绝对位置。
2.7 版新增:
SEEK_*常量
- seekable()
如果流支持随机访问,则返回
True。 如果False、seek()、tell() 和 truncate() 将引发IOError。
- tell()
返回当前流位置。
- truncate(size=None)
以字节为单位将流调整为给定的 size(如果未指定 size,则为当前位置)。 当前流位置不会改变。 这种调整大小可以扩展或减少当前文件的大小。 在扩展的情况下,新文件区域的内容取决于平台(在大多数系统上,附加字节是零填充的,在 Windows 上它们是不确定的)。 返回新文件大小。
- writable()
如果流支持写入,则返回
True。 如果False、write()和 truncate() 将引发IOError。
- writelines(lines)
将行列表写入流。 没有添加行分隔符,因此通常提供的每行末尾都有一个行分隔符。
- class io.RawIOBase
原始二进制 I/O 的基类。 它继承了IOBase。 没有公共构造函数。
原始二进制 I/O 通常提供对底层 OS 设备或 API 的低级访问,并且不会尝试将其封装在高级原语中(这留给缓冲 I/O 和文本 I/O,本文档稍后进行描述)页)。
除了 IOBase 的属性和方法,RawIOBase 还提供了以下方法:
- read(n=- 1)
从对象中读取最多 n 个字节并返回它们。 为方便起见,如果 n 未指定或为 -1,则调用 readall()。 否则,只进行一次系统调用。 如果操作系统调用返回少于 n 个字节,则可能返回少于 n 个字节。
如果返回 0 字节,并且 n 不为 0,则表示文件结束。 如果对象处于非阻塞模式并且没有可用字节,则返回
None。
- readall()
读取并返回流中的所有字节,直到 EOF,必要时使用对流的多次调用。
- readinto(b)
将最多 len(b) 个字节读入 b,并返回读取的字节数。 对象 b 应该是一个预先分配的、可写的字节数组,可以是 bytearray 或 memoryview。 如果对象处于非阻塞模式并且没有可用字节,则返回
None。
- write(b)
将 b 写入底层原始流,并返回写入的字节数。 对象 b 应该是一个字节数组,可以是
bytes、bytearray 或 memoryview。 返回值可以小于len(b),具体取决于底层原始流的细节,尤其是在非阻塞模式下。None。 此方法返回后,调用者可能会释放或变异 b,因此实现应仅在方法调用期间访问 b。
- class io.BufferedIOBase
支持某种缓冲的二进制流的基类。 它继承了IOBase。 没有公共构造函数。
与 RawIOBase 的主要区别在于方法 read()、readinto() 和 write() 将尝试(分别)读取尽可能多的输入或消耗所有给定的输出,代价是可能进行不止一个系统调用。
此外,如果底层原始流处于非阻塞模式并且无法获取或提供足够的数据,这些方法可能会引发 BlockingIOError; 与它们的 RawIOBase 对应物不同,它们永远不会返回
None。此外,read() 方法没有遵循 readinto() 的默认实现。
一个典型的 BufferedIOBase 实现不应该继承自 RawIOBase 实现,而是包装一个,就像 BufferedWriter 和 BufferedReader 一样。
BufferedIOBase 除了来自 IOBase 的方法和属性外,还提供或覆盖这些方法和属性:
- raw
BufferedIOBase 处理的底层原始流(RawIOBase 实例)。 这不是 BufferedIOBase API 的一部分,并且在某些实现中可能不存在。
- detach()
将底层原始流与缓冲区分开并返回。
原始流被分离后,缓冲区处于不可用状态。
某些缓冲区,如 BytesIO,没有从该方法返回的单个原始流的概念。 他们提出 UnsupportedOperation。
2.7 版中的新功能。
- read(n=- 1)
读取并返回最多 n 个字节。 如果省略参数,
None或负数,则读取并返回数据,直到达到 EOF。 如果流已经处于 EOF,则返回一个空字节对象。如果参数为正,并且底层原始流不是交互式的,则可能会发出多个原始读取以满足字节数(除非首先达到 EOF)。 但是对于交互式原始流,最多会发出一个原始读取,并且一个简短的结果并不意味着 EOF 迫在眉睫。
如果底层原始流处于非阻塞模式并且目前没有可用数据,则会引发 BlockingIOError。
- read1(n=- 1)
读取并返回最多 n 个字节,最多调用一次底层原始流的 read() 方法。 如果您在 BufferedIOBase 对象之上实现自己的缓冲,这会很有用。
- readinto(b)
将最多 len(b) 个字节读入 b,并返回读取的字节数。 对象 b 应该是一个预先分配的、可写的字节数组,可以是 bytearray 或 memoryview。
与 read() 一样,可以向底层原始流发出多次读取,除非后者是“交互式”的。
如果底层原始流处于非阻塞模式并且目前没有可用数据,则会引发 BlockingIOError。
- write(b)
写入 b,并返回写入的字节数(始终等于
len(b),因为如果写入失败,将引发IOError)。 对象 b 应该是一个字节数组,可以是bytes、bytearray 或 memoryview。 根据实际实现,这些字节可以很容易地写入底层流,或者出于性能和延迟原因保存在缓冲区中。在非阻塞模式下,如果需要将数据写入原始流但无法在不阻塞的情况下接受所有数据,则会引发 BlockingIOError。
此方法返回后,调用者可能会释放或变异 b,因此实现应仅在方法调用期间访问 b。
15.2.3. 原始文件 I/O
- class io.FileIO(name, mode='r', closefd=True)
FileIO 表示包含字节数据的操作系统级文件。 它实现了 RawIOBase 接口(因此也实现了 IOBase 接口)。
name 可以是以下两种情况之一:
一个字符串,表示将要打开的文件的路径;
一个整数,表示生成的 FileIO 对象将提供访问权限的现有操作系统级文件描述符的编号。
mode 可以是
'r'、'w'或'a',用于读取(默认)、写入或附加。 如果文件在打开写入或追加时不存在,则将创建该文件; 打开进行写入时,它将被截断。 在模式中添加'+'以允许同时读取和写入。此类上的
read()(使用正参数调用时)、readinto()和write()方法只会进行一次系统调用。除了来自 IOBase 和 RawIOBase 的属性和方法,FileIO 还提供了以下数据属性和方法:
- mode
构造函数中给出的模式。
- name
文件名。 当构造函数中没有给出名称时,这是文件的文件描述符。
15.2.4. 缓冲流
与原始 I/O 相比,缓冲 I/O 流为 I/O 设备提供了更高级别的接口。
- class io.BytesIO([initial_bytes])
使用内存字节缓冲区的流实现。 它继承了 BufferedIOBase。
可选参数 initial_bytes 是一个包含初始数据的
bytes对象。BytesIO 除了来自 BufferedIOBase 和 IOBase 的方法之外,还提供或覆盖这些方法:
- getvalue()
返回包含缓冲区全部内容的
bytes。
- read1()
在 BytesIO 中,这与
read()相同。
- class io.BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)
提供对可读、顺序 RawIOBase 对象的更高级别访问的缓冲区。 它继承了 BufferedIOBase。 从该对象读取数据时,可能会从底层原始流请求大量数据,并将其保存在内部缓冲区中。 然后可以在后续读取时直接返回缓冲数据。
构造函数为给定的可读 raw 流和 buffer_size 创建一个 BufferedReader。 如果省略 buffer_size,则使用 DEFAULT_BUFFER_SIZE。
BufferedReader 除了来自 BufferedIOBase 和 IOBase 的方法之外,还提供或覆盖这些方法:
- peek([n])
从流中返回字节而不推进位置。 最多对原始流进行一次读取以满足调用。 返回的字节数可能比请求的少或多。
- read([n])
读取并返回 n 字节,或者如果 n 未给出或为负,直到 EOF 或读取调用将在非阻塞模式下阻塞。
- read1(n)
读取并返回最多 n 个字节,仅对原始流进行一次调用。 如果至少缓冲了一个字节,则只返回缓冲的字节。 否则,将进行一次原始流读取调用。
- class io.BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)
提供对可写、顺序 RawIOBase 对象的更高级别访问的缓冲区。 它继承了 BufferedIOBase。 写入此对象时,数据通常保存在内部缓冲区中。 缓冲区将在各种条件下写入底层 RawIOBase 对象,包括:
当缓冲区对于所有待处理数据来说太小时;
当 flush() 被调用时;
当请求
seek()时(对于 BufferedRandom 对象);当 BufferedWriter 对象关闭或销毁时。
构造函数为给定的可写 raw 流创建一个 BufferedWriter。 如果未给出 buffer_size,则默认为 DEFAULT_BUFFER_SIZE。
支持第三个参数 max_buffer_size,但未使用和弃用。
BufferedWriter 除了来自 BufferedIOBase 和 IOBase 的方法之外,还提供或覆盖这些方法:
- flush()
强制将缓冲区中保存的字节放入原始流中。 如果原始流阻塞,则应引发 BlockingIOError。
- write(b)
写入b,返回写入的字节数。 对象 b 应该是一个字节数组,可以是
bytes、bytearray 或 memoryview。 在非阻塞模式下,如果需要写出缓冲区但原始流阻塞,则会引发 BlockingIOError。
- class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)
随机访问流的缓冲接口。 它继承了 BufferedReader 和 BufferedWriter,并进一步支持
seek()和tell()功能。构造函数为第一个参数中给出的可查找原始流创建读取器和写入器。 如果省略 buffer_size,则默认为 DEFAULT_BUFFER_SIZE。
支持第三个参数 max_buffer_size,但未使用和弃用。
BufferedRandom 可以做任何 BufferedReader 或 BufferedWriter 可以做的事情。
- class io.BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE)
一个缓冲的 I/O 对象将两个单向 RawIOBase 对象(一个可读,另一个可写)组合到一个双向端点中。 它继承了 BufferedIOBase。
reader 和 writer 分别是可读和可写的 RawIOBase 对象。 如果省略 buffer_size,则默认为 DEFAULT_BUFFER_SIZE。
支持第四个参数 max_buffer_size,但未使用和弃用。
BufferedRWPair 实现了所有 BufferedIOBase' 的方法,除了 detach(),它引发了 UnsupportedOperation。
警告
BufferedRWPair 不会尝试同步对其底层原始流的访问。 您不应该将与 reader 和 writer 相同的对象传递给它; 改用 BufferedRandom。
15.2.5. 文本输入/输出
- class io.TextIOBase
文本流的基类。 此类提供了一个基于 Unicode 字符和行的接口来流 I/O。 没有
readinto()方法,因为 Python 的 unicode 字符串是不可变的。 它继承了IOBase。 没有公共构造函数。TextIOBase 除了来自 IOBase 的数据属性和方法之外,还提供或覆盖这些数据属性和方法:
- encoding
用于将流的字节解码为字符串以及将字符串编码为字节的编码名称。
- errors
解码器或编码器的错误设置。
- newlines
一个字符串、一个字符串元组或
None,表示到目前为止翻译的换行符。 根据实现和初始构造函数标志,这可能不可用。
- buffer
TextIOBase 处理的底层二进制缓冲区(一个 BufferedIOBase 实例)。 这不是 TextIOBase API 的一部分,在某些实现中可能不存在。
- detach()
将底层二进制缓冲区与 TextIOBase 分开并返回。
底层缓冲区被分离后,TextIOBase 处于不可用状态。
某些 TextIOBase 实现,如 StringIO,可能没有底层缓冲区的概念,调用此方法将引发 UnsupportedOperation。
2.7 版中的新功能。
- read(n=- 1)
从流中读取并返回至多 n 个字符作为单个 unicode。 如果 n 为负数或
None,读取直到 EOF。
- readline(limit=- 1)
读到换行符或 EOF 并返回一个
unicode。 如果流已经在 EOF,则返回一个空字符串。如果指定了 limit,最多读取 limit 个字符。
- seek(offset, whence=SEEK_SET)
将流位置更改为给定的 offset。 行为取决于 whence 参数。 whence 的默认值为
SEEK_SET。SEEK_SET或0:从流开始寻找(默认); offset 必须是 TextIOBase.tell() 返回的数字,或者为零。 任何其他 offset 值都会产生未定义的行为。SEEK_CUR或1:“寻找”到当前位置; offset 必须为零,这是一个无操作(不支持所有其他值)。SEEK_END或2:寻找流的末尾; offset 必须为零(不支持所有其他值)。
将新的绝对位置作为不透明数字返回。
2.7 版新增:
SEEK_*常量。
- tell()
将当前流位置作为不透明数字返回。 该数字通常不代表底层二进制存储中的字节数。
- write(s)
将 unicode 字符串 s 写入流并返回写入的字符数。
- class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False)
BufferedIOBase 二进制流上的缓冲文本流。 它继承了 TextIOBase。
encoding 给出流将被解码或编码的编码名称。 它默认为 locale.getpreferredencoding()。
errors 是一个可选字符串,指定如何处理编码和解码错误。 如果存在编码错误,则通过
'strict'引发ValueError异常(默认None具有相同效果),或通过'ignore'忽略错误. (请注意,忽略编码错误会导致数据丢失。)'replace'会导致替换标记(例如'?')被插入到格式错误的数据处。 写入时,可以使用'xmlcharrefreplace'(替换为适当的 XML 字符引用)或'backslashreplace'(替换为反斜杠转义序列)。 任何其他已用 codecs.register_error() 注册的错误处理名称也是有效的。newline 控制如何处理行尾。 它可以是
None、、'\n'、'\r'和'\r\n'。 它的工作原理如下:在输入时,如果 newline 是
None,则启用 universal newlines 模式。 输入中的行可以以'\n'、'\r'或'\r\n'结尾,这些在返回给调用者之前会被转换为'\n'。 如果是,则启用通用换行符模式,但行尾未翻译返回给调用者。 如果它具有任何其他合法值,则输入行仅由给定的字符串终止,并且行尾未翻译地返回给调用者。在输出时,如果 newline 是
None,则写入的任何'\n'字符都将转换为系统默认行分隔符 os.linesep。 如果 newline 是,则不会发生转换。 如果 newline 是任何其他合法值,则写入的任何'\n'字符都将转换为给定的字符串。
如果 line_buffering 是
True,则当 write 调用包含换行符或回车符时,隐含flush()。TextIOWrapper 除了 TextIOBase 及其父级的属性之外,还提供了一个属性:
- line_buffering
是否启用行缓冲。
- class io.StringIO(initial_value=, newline='\\n')
unicode 文本的内存流。 它继承了 TextIOWrapper。
缓冲区的初始值可以通过提供 initial_value 来设置。 如果启用换行符转换,换行符将被编码为 write()。 流位于缓冲区的开头。
newline 参数的工作方式类似于 TextIOWrapper。 默认值是仅将
\n字符视为行尾,并且不进行换行转换。 如果newline设置为None,所有平台的换行符都写为\n,但读取时仍然进行通用换行解码。StringIO 除了来自 TextIOWrapper 及其父级的方法外,还提供此方法:
用法示例:
import io output = io.StringIO() output.write(u'First line.\n') output.write(u'Second line.\n') # Retrieve file contents -- this will be # u'First line.\nSecond line.\n' contents = output.getvalue() # Close object and discard memory buffer -- # .getvalue() will now raise an exception. output.close()
- class io.IncrementalNewlineDecoder
- 一个辅助编解码器,用于解码 通用换行符 模式的换行符。 它继承了 codecs.IncrementalDecoder。
15.2.6. 进阶课题
在这里,我们将讨论与上述具体 I/O 实现有关的几个高级主题。
15.2.6.1. 表现
15.2.6.1.1. 二进制输入/输出
通过即使在用户请求单个字节时也仅读取和写入大块数据,缓冲 I/O 旨在隐藏调用和执行操作系统的无缓冲 I/O 例程时的任何低效。 增益会因操作系统和执行的 I/O 类型而有很大差异(例如,在一些现代操作系统如 Linux 上,无缓冲磁盘 I/O 可以与缓冲 I/O 一样快)。 然而,最重要的是,无论平台和支持设备如何,缓冲 I/O 都将为您提供可预测的性能。 因此,最好使用缓冲 I/O 而不是非缓冲 I/O。
15.2.6.2. 多线程
FileIO 对象是线程安全的,因为它们包装的操作系统调用(例如 Unix 下的 read(2))也是线程安全的。
二进制缓冲对象(BufferedReader、BufferedWriter、BufferedRandom 和 BufferedRWPair 的实例)使用锁保护其内部结构; 因此一次从多个线程调用它们是安全的。
TextIOWrapper 对象不是线程安全的。
15.2.6.3. 重入性
二进制缓冲对象(BufferedReader、BufferedWriter、BufferedRandom 和 BufferedRWPair 的实例)不可重入。 虽然在正常情况下不会发生可重入调用,但如果您在 信号 处理程序中执行 I/O,它们可能会出现。 如果在已从同一线程 访问 的情况下再次尝试进入缓冲对象,则会引发 RuntimeError。
上述内容隐含地扩展到文本文件,因为 open() 函数会将缓冲对象包装在 TextIOWrapper 中。 这包括标准流,因此也会影响内置函数 print()。