io
---使用流的核心工具¶
源代码: Lib/io.py
概述¶
这个 io
模块提供了python处理各种类型I/O的主要工具。有三种主要类型的I/O: text I/O , binary I/O 和 raw I/O . 这些是通用类别,并且可以为每个类使用不同的后备存储。属于任何这些类别的具体对象称为 file object . 其他常用术语是 流动 和 file-like object .
独立于它的类别,每个具体的流对象也将具有不同的功能:它可以是只读的、只写的或读写的。它还可以允许任意随机访问(向前或向后搜索到任何位置),或者只允许顺序访问(例如,对于套接字或管道)。
所有流都对您提供给它们的数据类型非常小心。例如,给出 str
对象到 write()
二元流的方法将引发 TypeError
. 所以会给一个 bytes
对象到 write()
文本流的方法。
Text I/O¶
文本I/O预期和生成 str
物体。这意味着,每当备份存储本机由字节(如文件)组成时,数据的编码和解码都是透明的,并且可以选择性地转换特定于平台的换行符。
创建文本流的最简单方法是 open()
,可以选择指定编码::
f = open("myfile.txt", "r", encoding="utf-8")
内存中的文本流也可用作 StringIO
物体::
f = io.StringIO("some initial text data")
文本流API在以下文档中详细描述: TextIOBase
.
二进制输入输出¶
二进制I/O(也称为 buffered I/O 期待 bytes-like objects 生产 bytes
物体。不执行编码、解码或换行转换。这类流可以用于所有类型的非文本数据,也可以用于需要手动控制文本数据处理的情况。
创建二进制流的最简单方法是 open()
具有 'b'
在模式字符串中:
f = open("myfile.jpg", "rb")
内存中的二进制流也可用作 BytesIO
物体::
f = io.BytesIO(b"some initial binary data: \x00\x01")
二进制流API在 BufferedIOBase
.
其他库模块可以提供创建文本或二进制流的其他方法。参见 socket.socket.makefile()
例如。
原始输入输出¶
原始I/O(也称为 unbuffered I/O )通常用作二进制和文本流的低级构建块;直接从用户代码操作原始流很少有用。但是,可以通过在禁用缓冲的情况下以二进制模式打开文件来创建原始流:
f = open("myfile.jpg", "rb", buffering=0)
原始流API在 RawIOBase
.
高级模块接口¶
- io.open(file, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None)¶
这是内置的别名
open()
功能。提出一个 auditing event
open
带着论据path
,mode
,flags
.
- io.open_code(path)¶
以模式打开提供的文件
'rb'
. 当目的是将内容视为可执行代码时,应使用此函数。path
应该是str
一条绝对的道路。此函数的行为可能会被对
PyFile_SetOpenCodeHook()
. 但是,假设path
是一个str
一条绝对的道路,open_code(path)
应该总是表现得和open(path, 'rb')
. 覆盖该行为是为了对文件进行额外的验证或预处理。3.8 新版功能.
- exception io.BlockingIOError¶
这是内置的兼容性别名
BlockingIOError
例外。
- exception io.UnsupportedOperation¶
继承异常
OSError
和ValueError
在流上调用不支持的操作时引发的。
内存流¶
也可以使用 str
或 bytes-like object 作为一个读写文件。弦乐 StringIO
可以像在文本模式下打开的文件一样使用。 BytesIO
可以像使用二进制模式打开的文件一样使用。两者都提供随机访问的完整读写功能。
参见
sys
包含标准IO流:
sys.stdin
,sys.stdout
和sys.stderr
.
类层次结构¶
I/O流的实现被组织为类的层次结构。弗斯特 abstract base classes (abcs),用于指定流的各种类别,然后是提供标准流实现的具体类。
注解
抽象基类还提供一些方法的默认实现,以帮助实现具体的流类。例如,
BufferedIOBase
提供未优化的readinto()
和readline()
.
在I/O层次结构的顶部是抽象基类 IOBase
. 它定义了流的基本接口。但是,请注意,对流的读写之间没有分离;允许实现引发 UnsupportedOperation
如果它们不支持给定的操作。
这个 RawIOBase
ABC扩展 IOBase
. 它处理将字节读写到流中。 FileIO
子类 RawIOBase
为机器文件系统中的文件提供接口。
这个 BufferedIOBase
ABC扩展 IOBase
. 它处理原始二进制流上的缓冲 (RawIOBase
)它的子类, BufferedWriter
, BufferedReader
和 BufferedRWPair
缓冲区原始二进制流,它们分别是可读的、可写的以及可读和可写的。 BufferedRandom
为可查看的流提供缓冲接口。另一个 BufferedIOBase
子类, BytesIO
,是内存中字节的流。
这个 TextIOBase
ABC扩展 IOBase
. 它处理字节表示文本的流,并处理字符串之间的编码和解码。 TextIOWrapper
延伸 TextIOBase
,是缓冲原始流的缓冲文本接口 (BufferedIOBase
)。最后, StringIO
是用于文本的内存流。
参数名不属于规范的一部分,而只是 open()
用作关键字参数。
下表总结了 io
模块:
ABC |
继承 |
存根法 |
混合方法和特性 |
---|---|---|---|
|
|
||
|
继承 |
||
|
继承 |
||
|
继承 |
I/O基类¶
- class io.IOBase¶
所有I/O类的抽象基类,作用于字节流。没有公共构造函数。
此类为派生类可以选择性重写的许多方法提供空的抽象实现;默认实现表示无法读取、写入或查找的文件。
尽管
IOBase
不申报read()
或write()
因为它们的签名会有所不同,所以实现和客户机应该将这些方法视为接口的一部分。此外,实现可能会引发ValueError
(或)UnsupportedOperation
)当调用不支持的操作时。用于从文件读取或写入二进制数据的基本类型是
bytes
.其他 bytes-like objectsstr
数据。注意,在封闭流上调用任何方法(甚至查询)都是未定义的。实施可能会提高
ValueError
在这种情况下。IOBase
(及其子类)支持迭代器协议,这意味着IOBase
对象可以迭代以生成流中的行。根据流是二进制流(产生字节)还是文本流(产生字符串),行的定义略有不同。见readline()
下面。IOBase
也是一个上下文管理器,因此支持with
语句。在这个例子中, file 在with
语句的套件已完成---即使发生异常:with open('spam.txt', 'w') as file: file.write('Spam and eggs!')
IOBase
提供以下数据属性和方法:- close()¶
冲洗并关闭此流。如果文件已关闭,则此方法无效。关闭文件后,对该文件的任何操作(例如读取或写入)都将引发
ValueError
.为了方便起见,允许多次调用此方法;但是,只有第一次调用才有效果。
- closed¶
True
如果流已关闭。
- flush()¶
如果适用,刷新流的写缓冲区。这对只读和非阻塞流没有任何作用。
- isatty()¶
返回
True
如果流是交互式的(即连接到终端/tty设备)。
- readline(size=- 1)¶
从流中读取并返回一行。如果 size 最多指定 size 将读取字节。
行终止符总是
b'\n'
对于二进制文件;对于文本文件, newline 参数open()
可用于选择已识别的行终止符。
- readlines(hint=- 1)¶
读取并返回流中的行列表。 hint 可以指定以控制读取的行数:如果到目前为止所有行的总大小(字节/字符)超过 hint .
请注意,已经可以使用
for line in file: ...
不调用file.readlines()
.
- seek(offset, whence=SEEK_SET)¶
将流位置更改为给定的字节 抵消 . 抵消 是相对于 何处 . 的默认值 何处 是
SEEK_SET
. 值为 何处 是:SEEK_SET
或0
--流的开始(默认值); 抵消 应该是零或正SEEK_CUR
或1
--当前流位置; 抵消 可能是否定的SEEK_END
或2
--河流的尽头; 抵消 通常为阴性
返回新的绝对位置。
3.1 新版功能: 这个
SEEK_*
常量。3.3 新版功能: 一些操作系统可以支持其他值,比如
os.SEEK_HOLE
或os.SEEK_DATA
. 文件的有效值可能取决于它是以文本或二进制模式打开的。
- seekable()¶
返回
True
如果流支持随机访问。如果False
,seek()
,tell()
和truncate()
将提高OSError
.
- tell()¶
返回当前流位置。
- truncate(size=None)¶
将流调整为给定的 size 以字节为单位(或当前位置,如果 size 未指定)。当前流位置未更改。这种大小调整可以扩展或减小当前文件的大小。在扩展的情况下,新文件区域的内容取决于平台(在大多数系统上,额外的字节是零填充的)。返回新的文件大小。
在 3.5 版更改: Windows现在将在扩展时零填充文件。
- writable()¶
返回
True
如果流支持写入。如果False
,write()
和truncate()
将提高OSError
.
- writelines(lines)¶
将行列表写入流。不添加行分隔符,因此通常每个提供的行的末尾都有一个行分隔符。
- class io.RawIOBase¶
原始二进制流的基类。它继承了
IOBase
. 没有公共构造函数。原始二进制流通常提供对底层操作系统设备或API的低级访问,并且不尝试将其封装在高级原语中(此功能在缓冲二进制流和文本流中的更高级别上完成,本页稍后将介绍)。
- read(size=- 1)¶
读到 size 从对象返回的字节。为了方便起见,如果 size 未指定或-1,返回EOF之前的所有字节。否则,只进行一次系统调用。少于 size 如果操作系统调用返回的值小于 size 字节。
如果返回0字节,并且 size 不是0,这表示文件结束。如果对象处于非阻塞模式且没有可用字节,
None
返回。默认实现遵循
readall()
和readinto()
.
- readall()¶
读取并返回流中的所有字节,直到EOF,必要时使用对流的多个调用。
- readinto(b)¶
将字节读取到预先分配的、可写的 bytes-like object b b
bytearray
None
返回。
- write(b)¶
写出给定的 bytes-like object , b ,并返回写入的字节数。这个长度可以小于 b 以字节为单位,这取决于底层原始流的具体情况,尤其是当它处于非阻塞模式时。
None
如果原始流设置为不阻塞,并且没有单个字节可以轻易写入,则返回。调用者可能释放或变异 b 在这个方法返回之后,所以实现应该只访问 b 在方法调用期间。
- class io.BufferedIOBase¶
支持某种缓冲的二进制流的基类。它继承
IOBase
. 没有公共构造函数。主要区别在于
RawIOBase
是那种方法read()
,readinto()
和write()
将尝试(分别)读取尽可能多的输入或消耗所有给定的输出,代价可能是进行多个系统调用。此外,这些方法可以提高
BlockingIOError
如果基础原始流处于非阻塞模式,并且无法获取或提供足够的数据;与它们不同RawIOBase
对口人,他们永远不会回来None
.此外,
read()
方法没有默认实现,该实现将readinto()
.典型
BufferedIOBase
实现不应继承自RawIOBase
实现,但封装一个,比如BufferedWriter
和BufferedReader
做。BufferedIOBase
提供或重写这些数据属性和方法以及IOBase
:- raw¶
底层原始流(A
RawIOBase
实例)BufferedIOBase
处理。这不是BufferedIOBase
API和可能在某些实现上不存在。
- detach()¶
将底层的原始流与缓冲区分离并返回它。
分离原始流后,缓冲区处于不可用状态。
一些缓冲区,比如
BytesIO
,不具有从此方法返回的单个原始流的概念。他们提高UnsupportedOperation
.3.1 新版功能.
- read(size=- 1)¶
阅读并返回 size 字节。如果省略了参数,
None
或者为负,读取并返回数据,直到达到EOF。空的bytes
如果流已经位于eof,则返回对象。如果参数为正数,并且基础原始流不是交互式的,则可以发出多个原始读取以满足字节计数(除非先达到EOF)。但对于交互式原始流,最多会发出一个原始读取,而一个简短的结果并不意味着EOF即将到来。
A
BlockingIOError
如果基础原始流处于非阻塞模式,并且当前没有可用数据,则引发。
- read1([size])¶
阅读并返回 size 字节,最多一个对底层原始流的调用
read()
(或)readinto()
方法。如果您在BufferedIOBase
对象。如果 size 是
-1
(默认值),返回任意字节数(除非达到EOF,否则大于零)。
- readinto(b)¶
将字节读取到预先分配的、可写的 bytes-like object b b
bytearray
.类似于
read()
,可以向基础原始流发出多个读取,除非后者是交互式的。A
BlockingIOError
如果基础原始流处于非阻塞模式,并且当前没有可用数据,则引发。
- readinto1(b)¶
将字节读取到预先分配的、可写的 bytes-like object b ,最多使用一个对基础原始流的调用
read()
(或)readinto()
方法。返回读取的字节数。A
BlockingIOError
如果基础原始流处于非阻塞模式,并且当前没有可用数据,则引发。3.5 新版功能.
- write(b)¶
写出给定的 bytes-like object , b ,并返回写入的字节数(始终等于 b 以字节为单位,因为如果写入失败,
OSError
将被引发)。根据实际的实现,这些字节可以很容易地写入底层流,或者出于性能和延迟的原因保存在缓冲区中。当处于非阻塞模式时,A
BlockingIOError
如果数据需要写入原始流,但它无法在不阻塞的情况下接受所有数据,则引发。调用者可能释放或变异 b 在这个方法返回之后,所以实现应该只访问 b 在方法调用期间。
原始文件I/O¶
- class io.FileIO(name, mode='r', closefd=True, opener=None)¶
表示包含字节数据的操作系统级文件的原始二进制流。它继承了
RawIOBase
.这个 name 可以是两件事之一:
字符串或
bytes
对象,表示将打开的文件的路径。在这种情况下,closefd必须True
(默认)否则将引发错误。一个整数,表示现有操作系统级文件描述符的数目,结果
FileIO
对象将提供访问权限。当fileio对象关闭时,fd也将关闭,除非 特洛夫德 设置为False
.
这个 mode 可以是
'r'
,'w'
,'x'
或'a'
用于读取(默认)、写入、独占创建或附加。如果文件不存在,则在打开进行写入或追加时将创建该文件;打开进行写入时将截断该文件。FileExistsError
如果在打开以进行创建时它已存在,则将引发。打开用于创建的文件意味着写入,因此此模式的行为方式与'w'
. 添加一个'+'
到允许同时读写的模式。这个
read()
(当用肯定的参数调用时)readinto()
和write()
此类上的方法将只进行一次系统调用。通过将可调用的 开瓶器 . 然后通过调用 开瓶器 用( name , flags ) 开瓶器 必须返回打开的文件描述符(传递
os.open
作为 开瓶器 产生类似于传递的功能None
)新创建的文件是 non-inheritable .
见
open()
内置函数,例如使用 开瓶器 参数。在 3.3 版更改: 这个 开瓶器 已添加参数。这个
'x'
增加了模式。在 3.4 版更改: 文件现在不可继承。
FileIO
提供这些数据属性以及RawIOBase
和IOBase
:- mode¶
构造函数中给出的模式。
- name¶
文件名。这是在构造函数中没有给定名称时文件的文件描述符。
缓冲流¶
缓冲的I/O流为I/O设备提供了比原始I/O更高级别的接口。
- class io.BytesIO([initial_bytes])¶
使用内存字节缓冲区的二进制流。它继承了
BufferedIOBase
. 当close()
方法被调用。可选参数 initial_bytes 是一个 bytes-like object 包含初始数据的。
BytesIO
提供或重写这些方法以及BufferedIOBase
和IOBase
:- getbuffer()¶
返回对缓冲区内容的可读和可写视图,而不复制它们。此外,改变视图将透明地更新缓冲区的内容:
>>> b = io.BytesIO(b"abcdef") >>> view = b.getbuffer() >>> view[2:4] = b"56" >>> b.getvalue() b'ab56ef'
注解
只要视图存在,
BytesIO
无法调整或关闭对象的大小。3.2 新版功能.
- readinto1(b)¶
在
BytesIO
,这和readinto()
.3.5 新版功能.
- class io.BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE)¶
一种缓冲二进制流,提供对可读的、不可查找的高级访问
RawIOBase
原始二进制流。它继承了BufferedIOBase
.当从这个对象读取数据时,可以从底层原始流请求更大数量的数据,并将其保存在内部缓冲区中。缓冲后的数据可以在后续读取时直接返回。
构造函数创建一个
BufferedReader
对于给定的可读性 raw 流和 buffer_size . 如果 buffer_size 被省略,DEFAULT_BUFFER_SIZE
使用。BufferedReader
提供或重写这些方法以及BufferedIOBase
和IOBase
:- peek([size])¶
从流返回字节而不前进位置。为满足调用,在原始流上最多执行一次读取。返回的字节数可能小于或大于请求的字节数。
- read([size])¶
读并返回 size 字节,或者如果 size 直到EOF或如果读取调用将在非阻塞模式下阻塞,则不会给出或为负。
- read1([size])¶
阅读并返回 size 在原始流上只有一个调用的字节。如果缓冲了至少一个字节,则只返回缓冲字节。否则,将进行一个原始流读取调用。
在 3.7 版更改: 这个 size 参数现在是可选的。
- class io.BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)¶
一种缓冲二进制流,提供对可写、不可查找的高级访问
RawIOBase
原始二进制流。它继承了BufferedIOBase
.当写入这个对象时,数据通常被放入一个内部缓冲区。缓冲区将被写到底层
RawIOBase
各种条件下的物体,包括:当缓冲区对于所有挂起的数据太小时;
什么时候?
flush()
被称为;当A
seek()
请求(用于BufferedRandom
对象);当
BufferedWriter
对象被关闭或销毁。
构造函数创建一个
BufferedWriter
对于给定的可写 raw 溪流。如果 buffer_size 未给定,默认为DEFAULT_BUFFER_SIZE
.BufferedWriter
提供或重写这些方法以及BufferedIOBase
和IOBase
:- flush()¶
强制缓冲区中保留的字节进入原始流。一
BlockingIOError
如果原始流阻塞,则应引发。
- write(b)¶
写下 bytes-like object , b ,并返回写入的字节数。当处于非阻塞模式时,A
BlockingIOError
如果需要写出缓冲区但原始流阻塞,则引发。
- class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)¶
一种缓冲的二进制流,提供对一个可看见的
RawIOBase
原始二进制流。它继承了BufferedReader
和BufferedWriter
.构造函数为第一个参数中给定的可查找原始流创建读写器。如果 buffer_size 它默认为
DEFAULT_BUFFER_SIZE
.BufferedRandom
什么都能做BufferedReader
或BufferedWriter
seek()
和tell()
- class io.BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE)¶
一种缓冲二进制流,提供对两个不可查找的对象的高级访问
RawIOBase
原始二进制流——一个可读,另一个可写。它继承了BufferedIOBase
.读者 和*writer*是
RawIOBase
分别可读和可写的对象。如果 buffer_size 它默认为DEFAULT_BUFFER_SIZE
.BufferedRWPair
实现所有BufferedIOBase
的方法,除了detach()
提出UnsupportedOperation
.警告
BufferedRWPair
不尝试同步对其基础原始流的访问。您不应将它传递给与读写器相同的对象;请使用BufferedRandom
相反。
Text I/O¶
- class io.TextIOBase¶
文本流的基类。此类为流I/O提供基于字符和行的接口。它继承
IOBase
. 没有公共构造函数。TextIOBase
提供或重写这些数据属性和方法以及IOBase
:- encoding¶
用于将流的字节解码为字符串和将字符串编码为字节的编码的名称。
- errors¶
解码器或编码器的错误设置。
- newlines¶
字符串、字符串的元组,或
None
,表示到目前为止翻译的新行。根据实现和初始构造函数标志,这可能不可用。
- buffer¶
底层二进制缓冲区(A
BufferedIOBase
实例)TextIOBase
处理。这不是TextIOBase
API和可能在某些实现中不存在。
- detach()¶
将底层二进制缓冲区与
TextIOBase
然后把它还给我。在分离基础缓冲区之后,
TextIOBase
处于不可用状态。一些
TextIOBase
实现,比如StringIO
,可能没有基础缓冲区的概念,调用此方法将引发UnsupportedOperation
.3.1 新版功能.
- readline(size=- 1)¶
读到换行符或EOF并返回一个
str
. 如果流已处于EOF,则返回空字符串。如果 size 最多指定 size 将读取字符。
- seek(offset, whence=SEEK_SET)¶
将流位置更改为给定的 抵消 . 行为取决于 何处 参数。的默认值 何处 是
SEEK_SET
.SEEK_SET
或0
:从流的开始处搜索(默认); 抵消 必须是返回的数字TextIOBase.tell()
或零。任何其他 抵消 值产生未定义的行为。SEEK_CUR
或1
:“搜索”到当前位置; 抵消 必须为零,这是一个无操作(不支持所有其他值)。SEEK_END
或2
:寻找河流的尽头; 抵消 必须为零(不支持所有其他值)。
以不透明数字返回新的绝对位置。
3.1 新版功能: 这个
SEEK_*
常量。
- tell()¶
以不透明数字返回当前流位置。数字通常不代表底层二进制存储中的字节数。
- write(s)¶
写入字符串 s 返回写入的字符数。
- class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False)¶
提供对
BufferedIOBase
缓冲二进制流。它继承了TextIOBase
.encoding 给出将用其对流进行解码或编码的编码的名称。它默认为
locale.getpreferredencoding(False)
.errors 是一个可选字符串,指定如何处理编码和解码错误。通过
'strict'
养一个ValueError
如果存在编码错误(默认为None
有同样的效果),或通过'ignore'
忽略错误。(请注意,忽略编码错误会导致数据丢失。)'replace'
导致替换标记(例如'?'
)在存在格式错误数据的地方插入。'backslashreplace'
导致用反斜杠转义序列替换格式错误的数据。写作时,'xmlcharrefreplace'
(替换为适当的XML字符引用)或'namereplace'
(替换)\N{{...}}
可以使用转义序列)。已注册的任何其他错误处理名称codecs.register_error()
也是有效的。newline 控制如何处理行尾。它可以
None
,''
,'\n'
,'\r'
和'\r\n'
. 其工作原理如下:当从流中读取输入时,如果 换行符 是
None
, universal newlines 模式已启用。输入中的行可以结束于'\n'
,'\r'
或'\r\n'
它们被翻译成'\n'
在被传回给来电者之前。如果 换行符 是''
,通用换行模式已启用,但行尾将返回给未翻译的调用方。如果 换行符 具有任何其他合法值,输入行仅由给定字符串终止,行尾返回给调用方,不进行翻译。将输出写入流时,如果 newline 是
None
任何'\n'
写入的字符将转换为系统默认行分隔符,os.linesep
. 如果 newline 是''
或'\n'
,不进行翻译。如果 newline 是否有其他合法价值,任何'\n'
写入的字符被转换为给定的字符串。
如果 line_buffering 是
True
,flush()
当要写入的调用包含换行符或回车时暗示。如果 write_through 是
True
,调用write()
保证不会被缓冲:任何数据写入TextIOWrapper
对象被立即处理到其基础二进制文件 缓冲区 .在 3.3 版更改: 这个 write_through 已添加参数。
在 3.3 版更改: 默认值 encoding 现在是
locale.getpreferredencoding(False)
而不是locale.getpreferredencoding()
. 不要使用更改临时区域设置编码locale.setlocale()
,使用当前区域设置编码而不是用户首选的编码。TextIOWrapper
提供这些数据属性和方法以及TextIOBase
和IOBase
:- line_buffering¶
线路缓冲是否启用。
- write_through¶
写操作是否立即传递给底层二进制缓冲区。
3.7 新版功能.
- reconfigure(*[, encoding][, errors][, newline][, line_buffering][, write_through])¶
使用的新设置重新配置此文本流 encoding , errors , newline , line_buffering 和 write_through .
未指定参数保留当前设置,除非
errors='strict'
使用时 编码 已指定,但 错误 未指定。如果已经从流中读取了某些数据,则无法更改编码或换行。另一方面,可以在写入后更改编码。
此方法在设置新参数之前执行隐式流刷新。
3.7 新版功能.
- class io.StringIO(initial_value='', newline='\n')¶
使用内存中文本缓冲区的文本流。它继承了
TextIOBase
.当
close()
方法被调用。缓冲区的初始值可以通过提供 initial_value . 如果启用换行转换,换行将被编码为
write()
. 流位于缓冲区的起始处。这个 换行符 参数的工作方式和
TextIOWrapper
,但在将输出写入流时,如果 换行符 是None
,换行符编写为\n
在所有平台上。StringIO
除了提供TextIOBase
和IOBase
:示例用法:
import io output = io.StringIO() output.write('First line.\n') print('Second line.', file=output) # Retrieve file contents -- this will be # '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¶
为解码换行符的帮助编解码器 universal newlines 模式。它继承
codecs.IncrementalDecoder
.
性能¶
本节讨论所提供的具体I/O实现的性能。
二进制输入输出¶
即使在用户请求单个字节时,通过只读取和写入大块数据,缓冲I/O隐藏了调用和执行操作系统的未缓冲I/O例程的任何效率低下。增益取决于操作系统和执行的I/O类型。例如,在一些现代操作系统(如Linux)上,未缓冲磁盘I/O的速度可以与缓冲I/O的速度一样快。但底线是,缓冲I/O提供了可预测的性能,而不管平台和备份设备如何。因此,对于二进制数据,使用缓冲I/O而不是未缓冲I/O几乎总是更好的。
Text I/O¶
二进制存储(如文件)上的文本I/O比同一存储上的二进制I/O慢得多,因为它需要使用字符编解码器在Unicode和二进制数据之间进行转换。处理大量文本数据(如大型日志文件)时,这一点会变得明显。也, TextIOWrapper.tell()
和 TextIOWrapper.seek()
由于所使用的重建算法,两者都非常慢。
多线程¶
FileIO
对象在操作系统调用的范围内是线程安全的(例如 read(2)
在Unix下),它们封装也是线程安全的。
二进制缓冲对象(的实例 BufferedReader
, BufferedWriter
, BufferedRandom
和 BufferedRWPair
)使用锁保护它们的内部结构;因此一次从多个线程调用它们是安全的。
TextIOWrapper
对象不是线程安全的。
可重入¶
二进制缓冲对象(的实例 BufferedReader
, BufferedWriter
, BufferedRandom
和 BufferedRWPair
)不可重入。虽然可重入调用在正常情况下不会发生,但它们可能是在 signal
处理程序。如果线程试图重新输入它已经访问的缓冲对象,则 RuntimeError
被引发。注意,这并不禁止其他线程进入缓冲对象。
上面隐式扩展到文本文件,因为 open()
函数将缓冲对象包装在 TextIOWrapper
. 这包括标准流,因此会影响内置 print()
功能也一样。