python / 3.7.2rc1 / all / library-io.html

io-使用流的核心工具

源代码: Lib/io.py


Overview

io模块提供了 Python 的主要Function,用于处理各种类型的 I/O。 I/O 有三种主要类型:*文本 I/O *,*二进制 I/O 原始 I/O 。这些是通用类别,每个类别都可以使用各种后备存储。属于这些类别中任何一个的具体对象称为file object。其他常用术语是 stream file-like object *。

不受类别限制,每个具体的流对象还将具有各种Function:它可以是只读,只写或读写的。它还可以允许任意随机访问(向前或向后搜索到任何位置),或仅允许 Sequences 访问(例如,在套接字或管道的情况下)。

所有流都非常小心您提供给它们的数据类型。例如,将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")

TextIOBase文档中详细描述了文本流 API。

Binary I/O

二进制 I/O(也称为*缓冲 I/O *)期望bytes-like objects并产生bytes个对象。不执行编码,解码或换行转换。此类流可用于所有类型的非文本数据,并且还可以用于需要手动控制文本数据处理的情况。

创建二进制流的最简单方法是在模式字符串中使用open()'b'

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

内存中的二进制流也可用作BytesIO对象:

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

BufferedIOBase的文档中详细描述了二进制流 API。

其他库模块可能会提供创建文本或二进制流的其他方式。例如,请参见socket.socket.makefile()

Raw I/O

原始 I/O(也称为*非缓冲 I/O *)通常用作二进制和文本流的低级构建块;直接从用户代码操作原始流很少有用。不过,您可以pass在禁用缓冲的情况下以二进制模式打开文件来创建原始流:

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

RawIOBase的文档中详细描述了原始流 API。

高级模块接口

  • io. DEFAULT_BUFFER_SIZE

    • 一个 int,包含模块的缓冲 I/O 类使用的默认缓冲区大小。 open()尽可能使用文件的 blksize(由os.stat()获取)。
  • io. open(* file mode ='r' buffering = -1 encoding = None errors = None newline = None closefd = True opener = None *)

    • 这是内置open()函数的别名。

此函数使用参数pathmodeflags引发auditing event openmodeflags参数可能已被修改或从原始调用中推断出来。

  • io. open_code(* path *)
    • 以模式'rb'打开提供的文件。如果要将内容视为可执行代码,则应使用此Function。

path应该是str并且是绝对路径。

可以pass更早调用PyFile_SetOpenCodeHook()来覆盖此函数的行为。但是,假设pathstr且是绝对路径,则open_code(path)的行为应始终与open(path, 'rb')相同。覆盖行为是为了对文件进行其他验证或预处理。

3.8 版的新Function。

  • exception io. BlockingIOError

  • exception io. UnsupportedOperation

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

In-memory streams

也可以使用strbytes-like object作为读取和写入的文件。对于字符串StringIO可以像在文本模式下打开的文件一样使用。 BytesIO可以像在二进制模式下打开的文件一样使用。两者均具有随机访问的全部读写Function。

See also

Class hierarchy

I/O 流的实现被组织为类的层次结构。首先是抽象 Base Class(ABC),用于指定流的各种类别,然后是提供标准流实现的具体类。

Note

Note

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

I/O 层次结构的顶部是抽象 Base ClassIOBase。它定义了流的基本接口。但是请注意,对流的读取和写入之间没有分隔。如果实现不支持给定的操作,则允许它们提高UnsupportedOperation

RawIOBase ABC 扩展了IOBase。它负责将字节读取和写入流中。 FileIO子类RawIOBase为机器文件系统中的文件提供接口。

BufferedIOBase ABC 处理对原始字节流(RawIOBase)的缓冲。它的子类BufferedWriterBufferedReaderBufferedRWPair缓冲流是可读,可写的以及可读和可写的。 BufferedRandom为随机访问流提供了一个缓冲接口。另一个BufferedIOBase子类BytesIO是内存字节流。

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

参数名称不是规范的一部分,仅open()的参数打算用作关键字参数。

下表总结了io模块提供的 ABC:

ABC Inherits Stub Methods Mixin 方法和属性
IOBase filenoseektruncate closeclosed__enter____exit__flushisatty__iter____next__readablereadlinereadlinesseekabletellwritablewritelines
RawIOBase IOBase readintowrite 继承了IOBase个方法readreadall
BufferedIOBase IOBase detachreadread1write 继承了IOBase个方法readintoreadinto1
TextIOBase IOBase detachreadreadlinewrite 继承了IOBase个方法encodingerrorsnewlines

I/O 基本类别

  • 类别 io. IOBase
    • 所有 I/O 类的抽象 Base Class,作用于字节流。没有公共构造函数。

此类为派生类可以有选择地覆盖的许多方法提供了空的抽象实现。默认实现表示无法读取,写入或查找的文件。

尽管IOBase不会语句read()write(),因为它们的签名会有所不同,但实现和 Client 端应将这些方法视为接口的一部分。此外,在调用不支持的操作时,实现可能会引发ValueError(或UnsupportedOperation)。

用于从文件读取或写入文件的二进制数据的基本类型为bytes。其他bytes-like objects也被接受为方法参数。文本 I/O 类可处理str数据。

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

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

IOBase也是上下文 Management 器,因此支持with语句。在此示例中,* 3 *文件在with语句的套件完成后关闭-即使发生异常:

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

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

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

为方便起见,允许多次调用此方法。但是,只有第一个电话才会生效。

  • closed

    • True(如果流关闭)。
  • fileno ( )

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

    • 刷新流的写缓冲区(如果适用)。这对只读流和非阻塞流不起作用。
  • isatty ( )

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

    • 如果可以读取流,则返回True。如果False,则read()将加注OSError
  • readline(* size = -1 *)

    • 从流中读取并返回一行。如果指定* size ,最多将读取 size *个字节。

对于二进制文件,行终止符始终为b'\n';对于文本文件,open()的* newline *参数可用于选择识别的行终止符。

  • readlines(*提示= -1 *)
    • 从流中读取并返回行列表。可以指定* hint 来控制读取的行数:如果到目前为止所有行的总大小(以字节/字符为单位)超过 hint *,将不再读取更多行。

请注意,已经可以使用for line in file: ...迭代文件对象而无需调用file.readlines()

  • seek(* offset whence = SEEK_SET *)

    • 将流位置更改为给定的字节* offset *。 * offset 相对于 whence *指示的位置进行解释。 * whence *的默认值为SEEK_SET。 * whence *的值是:
  • SEEK_SET0 –流的开始(默认); 偏移量应为零或正数

  • SEEK_CUR1 –当前流位置; 偏移量可能为负

  • SEEK_END2 –流的结尾; 偏移通常为负

返回新的绝对位置。

版本 3.1 中的新Function:SEEK_*常量。

版本 3.3 中的新增Function:某些 os 可能支持其他值,例如os.SEEK_HOLEos.SEEK_DATA。文件的有效值可能取决于以文本或二进制模式打开的文件。

  • seekable ( )

  • tell ( )

    • 返回当前流的位置。
  • truncate(* size = None *)

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

在版本 3.5 中进行了更改:Windows 现在在扩展时将文件填充为零。

  • writable ( )

    • 如果流支持写入,则返回True。如果Falsewrite()truncate()将加注OSError
  • writelines()

    • 将行列表写入流中。不添加行分隔符,因此通常为每个提供的行的末尾都具有行分隔符。
  • __del__ ( )

    • 准备销毁对象。 IOBase提供了此方法的默认实现,该方法调用实例的close()方法。
  • 类别 io. RawIOBase

    • 原始二进制 I/O 的 Base Class。它继承了IOBase。没有公共构造函数。

原始二进制 I/O 通常提供对底层 OS 设备或 API 的低级别访问,并且不会try将其封装在高级基元中(这留给了缓冲 I/O 和文本 I/O,稍后将在本文档中进行介绍)页)。

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

  • read(* size = -1 *)
    • 从对象读取最多* size 个字节并返回它们。为了方便起见,如果未指定 size 或-1,则返回 EOF 之前的所有字节。否则,只会进行一次系统调用。如果 os 调用返回的字节数少于 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 *。
  • 类别 io. BufferedIOBase

    • 支持某种缓冲的二进制流的 Base Class。它继承了IOBase。没有公共构造函数。

RawIOBase的主要区别在于,方法read()readinto()write()将try(分别)读取请求的任意数量的 Importing 或消耗所有给定的输出,但以进行多个系统调用为代价。

另外,如果基础原始流处于非阻塞模式并且无法获取或提供足够的数据,则这些方法可以引发BlockingIOError;与他们的RawIOBase同行不同,他们永远不会返回None

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

典型的BufferedIOBase实现不应继承自RawIOBase实现,而应像BufferedWriterBufferedReader那样包装一个。

BufferedIOBase除了提供IOBase中的方法和属性外,还提供或覆盖这些方法和属性:

  • raw

  • detach ( )

    • 将底层原始流与缓冲区分开,然后将其返回。

分离原始流后,缓冲区处于不可用状态。

某些缓冲区(例如BytesIO)没有从该方法返回单个原始流的概念。他们加注UnsupportedOperation

3.1 版中的新Function。

  • read(* size = -1 *)
    • 读取并返回最多* size *个字节。如果Ellipsis该参数,None或否定参数,则会读取并返回数据,直到达到 EOF。如果流已经在 EOF 上,则返回一个空的bytes对象。

如果参数为正,并且基础原始流不是交互式的,则可以发出多个原始读取来满足字节数(除非先到达 EOF)。但是对于交互式原始流,最多将发出一个原始读取,并且简短的结果并不意味着即将发生 EOF。

如果基础原始流处于非阻塞模式,并且此时没有可用数据,则引发BlockingIOError

  • read1([* size *])
    • 读取并返回最多* size *个字节,最多调用一次底层的原始流的read()(或readinto())方法。如果要在BufferedIOBase对象的顶部实现自己的缓冲,这将很有用。

如果* size *为-1(默认值),则返回任意数量的字节(除非达到 EOF,否则大于零)。

  • readinto(* b *)
    • 将字节读取到预分配的可写bytes-like object * b 中,并返回读取的字节数。例如, b *可能是bytearray

read()一样,可以对基础原始流进行多次读取,除非后者是交互式的。

如果基础原始流处于非阻塞模式,并且此时没有可用数据,则引发BlockingIOError

  • readinto1(* b *)
    • 使用最多一次对基础原始流的read()(或readinto())方法的调用,将字节读取到预分配的可写bytes-like object * b *中。返回读取的字节数。

如果基础原始流处于非阻塞模式,并且此时没有可用数据,则引发BlockingIOError

3.5 版中的新Function。

  • write(* b *)
    • 写入给定的bytes-like object,* b ,并返回写入的字节数(始终等于 b *的字节长度,因为如果写入失败,将引发OSError)。取决于实际的实现方式,这些字节可以很容易地写入底层流,或者出于性能和延迟原因,可以保留在缓冲区中。

在非阻塞模式下,如果需要将数据写入原始流,则它会引发BlockingIOError,但是如果不阻塞就无法接受所有数据。

在此方法返回之后,调用者可以释放或更改* b ,因此实现应仅在方法调用期间访问 b *。

原始文件 I/O

    • class * io. FileIO(* name mode ='r' closefd = True opener = None *)
    • FileIO表示包含字节数据的 OS 级文件。它实现了RawIOBase接口(因此也实现了IOBase接口)。
  • name *可以是以下两项之一:
  • 字符串或bytes对象,表示将要打开的文件的路径。在这种情况下,closefd 必须为True(默认值),否则将引发错误。

  • 一个整数,表示结果FileIO对象将对其访问的现有 OS 级文件 Descriptors 的编号。当 FileIO 对象关闭时,该 fd 也将关闭,除非* closefd *设置为False

模式可以是'r''w''x''a',用于读取(默认),写入,互斥创建或附加。如果在打开以进行写入或追加时不存在该文件,则将创建该文件;打开书写时将被截断。 FileExistsError在创建时已经存在时将被引发。打开文件进行创建意味着要进行写入,因此此模式的行为类似于'w'。将'+'添加到该模式以允许同时读取和写入。

此类上的read()(使用正参数调用时),readinto()write()方法将仅进行一次系统调用。

可以pass将 callable 传递为* opener 来使用自定义打开器。然后pass使用( name flags )调用 opener *来获得文件对象的基础文件 Descriptors。 * opener 必须返回打开的文件 Descriptors(传递os.open作为 opener *导致的Function类似于传递None)。

新创建的文件是non-inheritable

有关使用* opener *参数的示例,请参见open()内置函数。

在版本 3.3 中更改:添加了* opener *参数。 'x'模式已添加。

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

除了IOBaseRawIOBase的属性和方法外,FileIO还提供以下数据属性:

  • mode

    • 构造函数中给定的模式。
  • name

    • 文件名当在构造函数中未给出名称时,这是文件的文件 Descriptors。

Buffered Streams

与原始 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'

Note

只要该视图存在,就不能调整BytesIO对象的大小或将其关闭。

3.2 版中的新Function。

  • getvalue ( )

    • 返回bytes,其中包含缓冲区的全部内容。
  • read1([* size *])

在 3.7 版中进行了更改:* size *参数现在是可选的。

3.5 版中的新Function。

    • class * io. BufferedReader(* raw buffer_size = DEFAULT_BUFFER_SIZE *)
    • 提供对可读的 SequencesRawIOBase对象的更高级别访问的缓冲区。它继承了BufferedIOBase。从此对象读取数据时,可能会从基础原始流中请求大量数据,并将其保存在内部缓冲区中。然后可以在后续读取时直接返回缓冲的数据。

构造函数为给定的可读* raw 流和 buffer_size 创建一个BufferedReader。如果Ellipsis buffer_size *,则使用DEFAULT_BUFFER_SIZE

BufferedReader除了BufferedIOBaseIOBase中的方法外,还提供或覆盖了这些方法:

  • peek([* size *])

    • 从流中返回字节,而无需提前位置。最多只能对原始流进行一次读取才能满足调用要求。返回的字节数可能少于或大于请求的字节数。
  • read([* size *])

    • 读取并返回* size 个字节,或者如果未提供 size *或为负,则直到 EOF 或 read 调用将在非阻塞模式下阻塞为止。
  • read1([* size *])

    • 仅对原始流进行一次调用,即可读取并返回最多* size *个字节。如果至少有一个字节被缓冲,则仅返回缓冲的字节。否则,将进行一个原始流读取调用。

在 3.7 版中进行了更改:* size *参数现在是可选的。

    • class * io. BufferedWriter(* raw buffer_size = DEFAULT_BUFFER_SIZE *)
    • 提供对可写 SequencesRawIOBase对象的更高级别访问的缓冲区。它继承了BufferedIOBase。写入该对象时,通常将数据放入内部缓冲区。在各种情况下,该缓冲区将被写到基础RawIOBase对象中,包括:
  • 当缓冲区对于所有未决数据而言变得太小时;

  • flush()被调用时;

  • 当请求seek()时(对于BufferedRandom个对象);

  • BufferedWriter对象关闭或销毁时。

构造函数为给定的可写* raw 流创建一个BufferedWriter。如果未指定 buffer_size *,则默认为DEFAULT_BUFFER_SIZE

BufferedWriter除了BufferedIOBaseIOBase中的方法外,还提供或覆盖了这些方法:

  • flush ( )

    • 将保留在缓冲区中的字节强制进入原始流。如果原始流阻塞,则应引发BlockingIOError
  • write(* b *)

    • 写入bytes-like object,* b *,并返回写入的字节数。在非阻塞模式下,如果需要写出缓冲区但原始流阻塞,则引发BlockingIOError
    • class * io. BufferedRandom(* raw buffer_size = DEFAULT_BUFFER_SIZE *)

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

BufferedRandom具备BufferedReaderBufferedWriter可以做的任何事情。另外,保证实现seek()tell()

  • 类别 io. BufferedRWPair(读取器写入器,* buffer_size = DEFAULT_BUFFER_SIZE *)
    • 一个缓冲的 I/O 对象,将两个单向RawIOBase对象(一个可读,另一个可写)组合到一个双向端点中。它继承了BufferedIOBase

BufferedRWPair实现BufferedIOBase的所有方法,但detach()引发UnsupportedOperation除外。

Warning

BufferedRWPair不会try同步对其基础原始流的访问。您不应将其与读写器传递给同Pair象;请改用BufferedRandom

Text I/O

  • 类别 io. TextIOBase
    • 文本流的 Base Class。此类提供基于字符和行的接口来流 I/O。它继承了IOBase。没有公共构造函数。

TextIOBase除了提供IOBase中的数据属性和方法外,还提供或覆盖这些数据属性和方法:

  • encoding

    • 用于将流的字节解码为字符串并将字符串编码为字节的编码名称。
  • errors

    • 解码器或编码器的错误设置。
  • newlines

    • 一个字符串,一个字符串 Tuples 或None,指示到目前为止已翻译的换行符。取决于实现和初始构造函数标志,这可能不可用。
  • buffer

  • detach ( )

    • 将底层二进制缓冲区与TextIOBase分开并返回。

分离基础缓冲区后,TextIOBase处于不可用状态。

某些TextIOBase实现(例如StringIO)可能没有底层缓冲区的概念,调用此方法将引发UnsupportedOperation

3.1 版中的新Function。

  • read(* size = -1 *)

    • 从流中读取并最多返回* size 个字符,作为单个str。如果 size *为负数或None,则读取直到 EOF。
  • readline(* size = -1 *)

    • 阅读直到换行符或 EOF 并返回一个str。如果流已经在 EOF 上,则返回一个空字符串。

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

  • seek(* offset whence = SEEK_SET *)

    • 将流位置更改为给定的* offset 。行为取决于 whence *参数。 * whence *的默认值为SEEK_SET
  • SEEK_SET0:从流的开头开始搜索(默认); * offset 必须是TextIOBase.tell()返回的数字或零。任何其他 offset *值都会产生不确定的行为。

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

  • SEEK_END2:搜索到流的结尾; 偏移必须为零(不支持所有其他值)。

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

版本 3.1 中的新Function:SEEK_*常量。

  • tell ( )

    • 以不透明数字返回当前流的位置。该数字通常不表示基础二进制存储中的字节数。
  • write(* s *)

    • 将字符串* s *写入流中,并返回写入的字符数。
    • class * io. TextIOWrapper(* buffer encoding = None errors = None newline = None line_buffering = False write_through = False *)
  • encoding *给出将用于解码或编码流的编码的名称。默认为locale.getpreferredencoding(False)

  • errors *是一个可选的字符串,它指定如何处理编码和解码错误。如果存在编码错误,则传递'strict'引发ValueError异常(缺省值None具有相同的效果),或者传递'ignore'来忽略错误。 (请注意,忽略编码错误会导致数据丢失.)'replace'会导致在数据格式错误的地方插入替换标记(例如'?')。 'backslashreplace'导致格式错误的数据被反斜杠转义序列替换。编写时,可以使用'xmlcharrefreplace'(用适当的 XML 字符引用替换)或'namereplace'(用\N{...}转义序列替换)。已向codecs.register_error()注册的任何其他错误处理名称也有效。

  • newline *控制行尾的处理方式。可以是None'''\n''\r''\r\n'。其工作方式如下:

  • 从流中读取 Importing 时,如果* newline *为None,则启用universal newlines模式。Importing 中的行可以以'\n''\r''\r\n'结尾,并且在返回给调用者之前,这些行会转换为'\n'。如果是'',则启用通用换行模式,但是行结尾不翻译就返回给呼叫者。如果它具有任何其他合法值,则 Importing 行仅由给定的字符串终止,并且该行的末尾不翻译就返回给调用方。

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

如果* line_buffering *为True,则在写调用包含换行符或回车符时隐含flush()

如果* write_through True,则保证不会缓冲对write()的调用:写在TextIOWrapper对象上的任何数据都会立即处理到其底层二进制 buffer *。

在版本 3.3 中更改:已添加* write_through *参数。

在版本 3.3 中更改:默认的* encoding *现在是locale.getpreferredencoding(False)而不是locale.getpreferredencoding()。不要使用locale.setlocale()临时更改语言环境编码,请使用当前的语言环境编码,而不要使用用户首选的编码。

TextIOWrapper除了TextIOBase及其 parent 的成员之外,还提供以下成员:

  • line_buffering

    • 是否启用行缓冲。
  • write_through

    • 是否将写入立即传递到基础二进制缓冲区。

3.7 版中的新Function。

  • reconfigure(** [,encoding] [,errors] [,newline] [,line_buffering] [,write_through] *)
    • 使用* encoding errors newline line_buffering write_through *的新设置重新配置此文本流。

未指定的参数保持当前设置,但当指定* encoding 但未指定 errors 时使用errors='strict'除外。

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

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

3.7 版中的新Function。

    • class * io. StringIO(* initial_value ='' newline =' n'*)
    • 文本 I/O 的内存流。调用close()方法时,将丢弃文本缓冲区。

可以pass提供* initial_value *来设置缓冲区的初始值。如果启用了换行翻译,则换行将被编码为write()。流位于缓冲区的开头。

  • newline 参数的作用类似于TextIOWrapper。默认设置是仅将\n个字符视为行尾,并且不进行换行翻译。如果将 newline *设置为None,则在所有平台上将换行符写入为\n,但是在读取时仍会执行通用换行符解码。

StringIO除了TextIOBase及其父级提供的方法外,还提供了此方法:

  • getvalue ( )
    • 返回一个包含缓冲区全部内容的str。尽管未更改流位置,但换行符的解码方式类似于read()

Example usage:

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()

Performance

本节讨论所提供的具体 I/O 实现的性能。

Binary I/O

pass即使在用户要求一个字节时也仅读取和写入大块数据,缓冲的 I/O 可以掩盖调用和执行 os 的非缓冲 I/O 例程的任何低效率。增益取决于 OS 和执行的 I/O 类型。例如,在某些现代 os(例如 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类似。

Multi-threading

FileIO对象是线程安全的,以至于它们包装的 os 调用(例如 Unix 下的read(2))也是线程安全的。

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

TextIOWrapper对象不是线程安全的。

Reentrancy

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

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