io ---使用流的核心工具

源代码: Lib/io.py


概述

这个 io 模块提供了python处理各种类型I/O的主要工具。有三种主要类型的I/O: text I/Obinary I/Oraw I/O . 这些是通用类别,并且可以为每个类使用不同的后备存储。属于任何这些类别的具体对象称为 file object . 其他常用术语是 流动file-like object .

独立于它的类别,每个具体的流对象也将具有不同的功能:它可以是只读的、只写的或读写的。它还可以允许任意随机访问(向前或向后搜索到任何位置),或者只允许顺序访问(例如,对于套接字或管道)。

所有流都对您提供给它们的数据类型非常小心。例如,给出 str 对象到 write() 二元流的方法将引发 TypeError . 所以会给一个 bytes 对象到 write() 文本流的方法。

在 3.3 版更改: 用于引发的操作 IOError 现在提高 OSError ,因为 IOError 现在是的别名 OSError .

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.DEFAULT_BUFFER_SIZE

包含模块的缓冲I/O类使用的默认缓冲区大小的int。 open() 使用文件的blksize(由 os.stat() 如果可能的话。

io.open(file, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

这是内置的别名 open() 功能。

提出一个 auditing event open 带着论据 pathmodeflags .

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

继承异常 OSErrorValueError 在流上调用不支持的操作时引发的。

内存流

也可以使用 strbytes-like object 作为一个读写文件。弦乐 StringIO 可以像在文本模式下打开的文件一样使用。 BytesIO 可以像使用二进制模式打开的文件一样使用。两者都提供随机访问的完整读写功能。

参见

sys

包含标准IO流: sys.stdinsys.stdoutsys.stderr .

类层次结构

I/O流的实现被组织为类的层次结构。弗斯特 abstract base classes (abcs),用于指定流的各种类别,然后是提供标准流实现的具体类。

注解

抽象基类还提供一些方法的默认实现,以帮助实现具体的流类。例如, BufferedIOBase 提供未优化的 readinto()readline() .

在I/O层次结构的顶部是抽象基类 IOBase . 它定义了流的基本接口。但是,请注意,对流的读写之间没有分离;允许实现引发 UnsupportedOperation 如果它们不支持给定的操作。

这个 RawIOBase ABC扩展 IOBase . 它处理将字节读写到流中。 FileIO 子类 RawIOBase 为机器文件系统中的文件提供接口。

这个 BufferedIOBase ABC扩展 IOBase . 它处理原始二进制流上的缓冲 (RawIOBase )它的子类, BufferedWriterBufferedReaderBufferedRWPair 缓冲区原始二进制流,它们分别是可读的、可写的以及可读和可写的。 BufferedRandom 为可查看的流提供缓冲接口。另一个 BufferedIOBase 子类, BytesIO ,是内存中字节的流。

这个 TextIOBase ABC扩展 IOBase . 它处理字节表示文本的流,并处理字符串之间的编码和解码。 TextIOWrapper 延伸 TextIOBase ,是缓冲原始流的缓冲文本接口 (BufferedIOBase )。最后, StringIO 是用于文本的内存流。

参数名不属于规范的一部分,而只是 open() 用作关键字参数。

下表总结了 io 模块:

ABC

继承

存根法

混合方法和特性

IOBase

fileno, seek, and truncate

close, closed, __enter__, __exit__, flush, isatty, __iter__, __next__, readable, readline, readlines, seekable, tell, writable, and writelines

RawIOBase

IOBase

readinto and write

继承 IOBase 方法, readreadall

BufferedIOBase

IOBase

detach, read, read1, and write

继承 IOBase 方法, readintoreadinto1

TextIOBase

IOBase

detach, read, readline, and write

继承 IOBase 方法, encodingerrorsnewlines

I/O基类

class io.IOBase

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

此类为派生类可以选择性重写的许多方法提供空的抽象实现;默认实现表示无法读取、写入或查找的文件。

尽管 IOBase 不申报 read()write() 因为它们的签名会有所不同,所以实现和客户机应该将这些方法视为接口的一部分。此外,实现可能会引发 ValueError (或) UnsupportedOperation )当调用不支持的操作时。

用于从文件读取或写入二进制数据的基本类型是 bytes .其他 bytes-like objects str 数据。

注意,在封闭流上调用任何方法(甚至查询)都是未定义的。实施可能会提高 ValueError 在这种情况下。

IOBase (及其子类)支持迭代器协议,这意味着 IOBase 对象可以迭代以生成流中的行。根据流是二进制流(产生字节)还是文本流(产生字符串),行的定义略有不同。见 readline() 下面。

IOBase 也是一个上下文管理器,因此支持 with 语句。在这个例子中, filewith 语句的套件已完成---即使发生异常:

with open('spam.txt', 'w') as file:
    file.write('Spam and eggs!')

IOBase 提供以下数据属性和方法:

close()

冲洗并关闭此流。如果文件已关闭,则此方法无效。关闭文件后,对该文件的任何操作(例如读取或写入)都将引发 ValueError .

为了方便起见,允许多次调用此方法;但是,只有第一次调用才有效果。

closed

True 如果流已关闭。

fileno()

返回流的基础文件描述符(整数)(如果存在)。安 OSError 如果IO对象不使用文件描述符,则引发。

flush()

如果适用,刷新流的写缓冲区。这对只读和非阻塞流没有任何作用。

isatty()

返回 True 如果流是交互式的(即连接到终端/tty设备)。

readable()

返回 True 如果可以读取流。如果 Falseread() 将提高 OSError .

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_SET0 --流的开始(默认值); 抵消 应该是零或正

  • SEEK_CUR1 --当前流位置; 抵消 可能是否定的

  • SEEK_END2 --河流的尽头; 抵消 通常为阴性

返回新的绝对位置。

3.1 新版功能: 这个 SEEK_* 常量。

3.3 新版功能: 一些操作系统可以支持其他值,比如 os.SEEK_HOLEos.SEEK_DATA . 文件的有效值可能取决于它是以文本或二进制模式打开的。

seekable()

返回 True 如果流支持随机访问。如果 Falseseek()tell()truncate() 将提高 OSError .

tell()

返回当前流位置。

truncate(size=None)

将流调整为给定的 size 以字节为单位(或当前位置,如果 size 未指定)。当前流位置未更改。这种大小调整可以扩展或减小当前文件的大小。在扩展的情况下,新文件区域的内容取决于平台(在大多数系统上,额外的字节是零填充的)。返回新的文件大小。

在 3.5 版更改: Windows现在将在扩展时零填充文件。

writable()

返回 True 如果流支持写入。如果 Falsewrite()truncate() 将提高 OSError .

writelines(lines)

将行列表写入流。不添加行分隔符,因此通常每个提供的行的末尾都有一个行分隔符。

__del__()

准备销毁物体。 IOBase 提供此方法的默认实现,该方法调用实例的 close() 方法。

class io.RawIOBase

原始二进制流的基类。它继承了 IOBase . 没有公共构造函数。

原始二进制流通常提供对底层操作系统设备或API的低级访问,并且不尝试将其封装在高级原语中(此功能在缓冲二进制流和文本流中的更高级别上完成,本页稍后将介绍)。

RawIOBase 除了来自 IOBase

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 objectb ,并返回写入的字节数。这个长度可以小于 b 以字节为单位,这取决于底层原始流的具体情况,尤其是当它处于非阻塞模式时。 None 如果原始流设置为不阻塞,并且没有单个字节可以轻易写入,则返回。调用者可能释放或变异 b 在这个方法返回之后,所以实现应该只访问 b 在方法调用期间。

class io.BufferedIOBase

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

主要区别在于 RawIOBase 是那种方法 read()readinto()write() 将尝试(分别)读取尽可能多的输入或消耗所有给定的输出,代价可能是进行多个系统调用。

此外,这些方法可以提高 BlockingIOError 如果基础原始流处于非阻塞模式,并且无法获取或提供足够的数据;与它们不同 RawIOBase 对口人,他们永远不会回来 None .

此外, read() 方法没有默认实现,该实现将 readinto() .

典型 BufferedIOBase 实现不应继承自 RawIOBase 实现,但封装一个,比如 BufferedWriterBufferedReader 做。

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 objectb ,并返回写入的字节数(始终等于 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() 此类上的方法将只进行一次系统调用。

通过将可调用的 开瓶器 . 然后通过调用 开瓶器 用( nameflags开瓶器 必须返回打开的文件描述符(传递 os.open 作为 开瓶器 产生类似于传递的功能 None

新创建的文件是 non-inheritable .

open() 内置函数,例如使用 开瓶器 参数。

在 3.3 版更改: 这个 开瓶器 已添加参数。这个 'x' 增加了模式。

在 3.4 版更改: 文件现在不可继承。

FileIO 提供这些数据属性以及 RawIOBaseIOBase

mode

构造函数中给出的模式。

name

文件名。这是在构造函数中没有给定名称时文件的文件描述符。

缓冲流

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

class io.BytesIO([initial_bytes])

使用内存字节缓冲区的二进制流。它继承了 BufferedIOBase . 当 close() 方法被调用。

可选参数 initial_bytes 是一个 bytes-like object 包含初始数据的。

BytesIO 提供或重写这些方法以及 BufferedIOBaseIOBase

getbuffer()

返回对缓冲区内容的可读和可写视图,而不复制它们。此外,改变视图将透明地更新缓冲区的内容:

>>> b = io.BytesIO(b"abcdef")
>>> view = b.getbuffer()
>>> view[2:4] = b"56"
>>> b.getvalue()
b'ab56ef'

注解

只要视图存在, BytesIO 无法调整或关闭对象的大小。

3.2 新版功能.

getvalue()

返回 bytes 包含缓冲区的全部内容。

read1([size])

BytesIO ,这和 read() .

在 3.7 版更改: 这个 size 参数现在是可选的。

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 提供或重写这些方法以及 BufferedIOBaseIOBase

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 提供或重写这些方法以及 BufferedIOBaseIOBase

flush()

强制缓冲区中保留的字节进入原始流。一 BlockingIOError 如果原始流阻塞,则应引发。

write(b)

写下 bytes-like objectb ,并返回写入的字节数。当处于非阻塞模式时,A BlockingIOError 如果需要写出缓冲区但原始流阻塞,则引发。

class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)

一种缓冲的二进制流,提供对一个可看见的 RawIOBase 原始二进制流。它继承了 BufferedReaderBufferedWriter .

构造函数为第一个参数中给定的可查找原始流创建读写器。如果 buffer_size 它默认为 DEFAULT_BUFFER_SIZE .

BufferedRandom 什么都能做 BufferedReaderBufferedWriter 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 新版功能.

read(size=- 1)

最多读取和返回 size 将流中的字符作为单个字符 str . 如果 size 是否定的还是 None ,直到结束。

readline(size=- 1)

读到换行符或EOF并返回一个 str . 如果流已处于EOF,则返回空字符串。

如果 size 最多指定 size 将读取字符。

seek(offset, whence=SEEK_SET)

将流位置更改为给定的 抵消 . 行为取决于 何处 参数。的默认值 何处SEEK_SET .

  • SEEK_SET0 :从流的开始处搜索(默认); 抵消 必须是返回的数字 TextIOBase.tell() 或零。任何其他 抵消 值产生未定义的行为。

  • SEEK_CUR1 :“搜索”到当前位置; 抵消 必须为零,这是一个无操作(不支持所有其他值)。

  • SEEK_END2 :寻找河流的尽头; 抵消 必须为零(不支持所有其他值)。

以不透明数字返回新的绝对位置。

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' . 其工作原理如下:

  • 当从流中读取输入时,如果 换行符Noneuniversal newlines 模式已启用。输入中的行可以结束于 '\n''\r''\r\n' 它们被翻译成 '\n' 在被传回给来电者之前。如果 换行符'' ,通用换行模式已启用,但行尾将返回给未翻译的调用方。如果 换行符 具有任何其他合法值,输入行仅由给定字符串终止,行尾返回给调用方,不进行翻译。

  • 将输出写入流时,如果 newlineNone 任何 '\n' 写入的字符将转换为系统默认行分隔符, os.linesep . 如果 newline'''\n' ,不进行翻译。如果 newline 是否有其他合法价值,任何 '\n' 写入的字符被转换为给定的字符串。

如果 line_bufferingTrueflush() 当要写入的调用包含换行符或回车时暗示。

如果 write_throughTrue ,调用 write() 保证不会被缓冲:任何数据写入 TextIOWrapper 对象被立即处理到其基础二进制文件 缓冲区 .

在 3.3 版更改: 这个 write_through 已添加参数。

在 3.3 版更改: 默认值 encoding 现在是 locale.getpreferredencoding(False) 而不是 locale.getpreferredencoding() . 不要使用更改临时区域设置编码 locale.setlocale() ,使用当前区域设置编码而不是用户首选的编码。

TextIOWrapper 提供这些数据属性和方法以及 TextIOBaseIOBase

line_buffering

线路缓冲是否启用。

write_through

写操作是否立即传递给底层二进制缓冲区。

3.7 新版功能.

reconfigure(*[, encoding][, errors][, newline][,                      line_buffering][, write_through])

使用的新设置重新配置此文本流 encodingerrorsnewlineline_bufferingwrite_through .

未指定参数保留当前设置,除非 errors='strict' 使用时 编码 已指定,但 错误 未指定。

如果已经从流中读取了某些数据,则无法更改编码或换行。另一方面,可以在写入后更改编码。

此方法在设置新参数之前执行隐式流刷新。

3.7 新版功能.

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

使用内存中文本缓冲区的文本流。它继承了 TextIOBase .

close() 方法被调用。

缓冲区的初始值可以通过提供 initial_value . 如果启用换行转换,换行将被编码为 write() . 流位于缓冲区的起始处。

这个 换行符 参数的工作方式和 TextIOWrapper ,但在将输出写入流时,如果 换行符None ,换行符编写为 \n 在所有平台上。

StringIO 除了提供 TextIOBaseIOBase

getvalue()

返回A str 包含缓冲区的全部内容。新行被解码为 read() 尽管流位置没有更改。

示例用法:

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() 由于所使用的重建算法,两者都非常慢。

StringIO 但是,它是一个本机内存中的Unicode容器,并且将显示类似于 BytesIO .

多线程

FileIO 对象在操作系统调用的范围内是线程安全的(例如 read(2) 在Unix下),它们封装也是线程安全的。

二进制缓冲对象(的实例 BufferedReaderBufferedWriterBufferedRandomBufferedRWPair )使用锁保护它们的内部结构;因此一次从多个线程调用它们是安全的。

TextIOWrapper 对象不是线程安全的。

可重入

二进制缓冲对象(的实例 BufferedReaderBufferedWriterBufferedRandomBufferedRWPair )不可重入。虽然可重入调用在正常情况下不会发生,但它们可能是在 signal 处理程序。如果线程试图重新输入它已经访问的缓冲对象,则 RuntimeError 被引发。注意,这并不禁止其他线程进入缓冲对象。

上面隐式扩展到文本文件,因为 open() 函数将缓冲对象包装在 TextIOWrapper . 这包括标准流,因此会影响内置 print() 功能也一样。