io
--- 處理流的核心工具?
源代碼: Lib/io.py
概述?
io
模塊提供了 Python 用于處理各種 I/O 類型的主要工具。三種主要的 I/O類型分別為: 文本 I/O, 二進制 I/O 和 原始 I/O。這些是泛型類型,有很多種后端存儲可以用在他們上面。一個隸屬于任何這些類型的具體對象被稱作 file object。 其他同類的術語還有 流 和 類文件對象。
獨立于其類別,每個具體流對象也將具有各種功能:它可以是只讀,只寫或讀寫。它還可以允許任意隨機訪問(向前或向后尋找任何位置),或僅允許順序訪問(例如在套接字或管道的情況下)。
所有流對提供給它們的數(shù)據(jù)類型都很敏感。例如將 str
對象給二進制流的 write()
方法會引發(fā) TypeError
。將 bytes
對象提供給文本流的 write()
方法也是如此。
文本 I/O?
文本I/O預期并生成 str
對象。這意味著,無論何時后臺存儲是由字節(jié)組成的(例如在文件的情況下),數(shù)據(jù)的編碼和解碼都是透明的,并且可以選擇轉換特定于平臺的換行符。
創(chuàng)建文本流的最簡單方法是使用 open()
,可以選擇指定編碼:
f = open("myfile.txt", "r", encoding="utf-8")
內(nèi)存中文本流也可以作為 StringIO
對象使用:
f = io.StringIO("some initial text data")
TextIOBase
的文檔中詳細描述了文本流的API
二進制 I/O?
二進制I/O(也稱為緩沖I/O)預期 bytes-like objects 并生成 bytes
對象。不執(zhí)行編碼、解碼或換行轉換。這種類型的流可以用于所有類型的非文本數(shù)據(jù),并且還可以在需要手動控制文本數(shù)據(jù)的處理時使用。
創(chuàng)建二進制流的最簡單方法是使用 open()
,并在模式字符串中指定 'b'
:
f = open("myfile.jpg", "rb")
內(nèi)存中二進制流也可以作為 BytesIO
對象使用:
f = io.BytesIO(b"some initial binary data: \x00\x01")
BufferedIOBase
的文檔中詳細描述了二進制流 API。
其他庫模塊可以提供額外的方式來創(chuàng)建文本或二進制流。參見 socket.socket.makefile()
的示例。
原始 I/O?
原始 I/O(也稱為 非緩沖 I/O)通常用作二進制和文本流的低級構建塊。用戶代碼直接操作原始流的用法非常罕見。不過,可以通過在禁用緩沖的情況下以二進制模式打開文件來創(chuàng)建原始流:
f = open("myfile.jpg", "rb", buffering=0)
RawIOBase
的文檔中詳細描述了原始流的API
文本編碼格式?
The default encoding of TextIOWrapper
and open()
is
locale-specific (locale.getencoding()
).
但是,很多開發(fā)者在打開以 UTF-8 編碼的文本文件 (例如 JSON, TOML, Markdown 等等...) 時會忘記指定編碼格式,因為大多數(shù) Unix 平臺默認使用 UTF-8 語言區(qū)域。 這會導致各種錯誤因為大多數(shù) Windows 用戶的語言區(qū)域編碼格式并不是 UTF-8。 例如:
# May not work on Windows when non-ASCII characters in the file.
with open("README.md") as f:
long_description = f.read()
此外,雖然暫時還沒有確定的計劃,但 Python 可能會在未來將默認的文本文件編碼格式改為 UTF-8。
為此,強烈建議你在打開文本文件時顯式地指定編碼格式。 如果你想要使用 UTF-8,請傳入 encoding="utf-8"
。 要使用當前語言區(qū)域的編碼格式,encoding="locale"
已在 Python 3.10 中被支持。
When you need to run existing code on Windows that attempts to open UTF-8 files using the default locale encoding, you can enable the UTF-8 mode. See UTF-8 mode on Windows.
選擇性的 EncodingWarning?
3.10 新版功能: 請參閱 PEP 597 了解詳情。
要找出哪里使用了默認語言區(qū)域的編碼格式,你可以啟用 -X warn_default_encoding
命令行選項或設置 PYTHONWARNDEFAULTENCODING
環(huán)境變量,這將在使用默認編碼格式時發(fā)出 EncodingWarning
。
如果你提供了使用 open()
或 TextIOWrapper
的 API 并將 encoding=None
作為形參傳入,你可以使用 text_encoding()
以便 API 的調(diào)用方在沒有傳入 encoding
的時候?qū)l(fā)出 EncodingWarning
。 但是,對于新的 API 請考慮默認就使用 UTF-8 (即 encoding="utf-8"
)。
高階模塊接口?
- io.DEFAULT_BUFFER_SIZE?
包含模塊緩沖 I/O 類使用的默認緩沖區(qū)大小的 int。 在可能的情況下
open()
將使用文件的 blksize(由os.stat()
獲得)。
- io.open(file, mode='r', buffering=- 1, encoding=None, errors=None, newline=None, closefd=True, opener=None)?
這是內(nèi)置的
open()
函數(shù)的別名。open
附帶參數(shù)path
、mode
、flags
會引發(fā) 審計事件。
- io.open_code(path)?
以
'rb'
模式打開提供的文件。如果目的是將文件內(nèi)容做為可執(zhí)行代碼,則應使用此函數(shù)。path
應當為str
類型并且是一個絕對路徑。此函數(shù)的行為可以由對
PyFile_SetOpenCodeHook()
的先期調(diào)用所重載。 但是,如果path
為str
類型并且是一個絕對路徑,open_code(path)
的行為應當總是與open(path, 'rb')
一致。 重載此行為的目的是為了給文件附加額外的驗證或預處理。3.8 新版功能.
- io.text_encoding(encoding, stacklevel=2, /)?
這是一個針對使用
open()
或TextIOWrapper
的可調(diào)用對象的輔助函數(shù)并且具有encoding=None
形參。This function returns encoding if it is not
None
. Otherwise, it returns"locale"
or"utf-8"
depending on UTF-8 Mode.This function emits an
EncodingWarning
ifsys.flags.warn_default_encoding
is true and encoding isNone
. stacklevel specifies where the warning is emitted. For example:def read_text(path, encoding=None): encoding = io.text_encoding(encoding) # stacklevel=2 with open(path, encoding) as f: return f.read()
在這個例子中,將為
read_text()
的調(diào)用方發(fā)出EncodingWarning
。請參閱 文本編碼格式 了解更多信息。
3.10 新版功能.
在 3.11 版更改:
text_encoding()
returns "utf-8" when UTF-8 mode is enabled and encoding isNone
.
- exception io.BlockingIOError?
這是內(nèi)置的
BlockingIOError
異常的兼容性別名。
- exception io.UnsupportedOperation?
在流上調(diào)用不支持的操作時引發(fā)的繼承
OSError
和ValueError
的異常。
參見
sys
包含標準IO流:
sys.stdin
,sys.stdout
和sys.stderr
。
類的層次結構?
I/O 流被安排為按類的層次結構實現(xiàn)。 首先是 抽象基類 (ABC),用于指定流的各種類別,然后是提供標準流實現(xiàn)的具體類。
備注
抽象基類還提供某些方法的默認實現(xiàn),以幫助實現(xiàn)具體的流類。例如
BufferedIOBase
提供了readinto()
和readline()
的未優(yōu)化實現(xiàn)。
I/O層次結構的頂部是抽象基類 IOBase
。它定義了流的基本接口。但是請注意,對流的讀取和寫入之間沒有分離。如果實現(xiàn)不支持指定的操作,則會引發(fā) UnsupportedOperation
。
抽象基類 RawIOBase
是 IOBase
的子類。它負責將字節(jié)讀取和寫入流中。 RawIOBase
的子類 FileIO
提供計算機文件系統(tǒng)中文件的接口。
抽象基類 BufferedIOBase
繼承了 IOBase
,處理原始二進制流( RawIOBase
)上的緩沖。其子類 BufferedWriter
、 BufferedReader
和 BufferedRWPair
分別緩沖可讀、可寫以及可讀寫的原始二進制流。 BufferedRandom
提供了帶緩沖的可隨機訪問流接口。 BufferedIOBase
的另一個子類 BytesIO
是內(nèi)存中字節(jié)流。
抽象基類 TextIOBase
繼承了 IOBase
。它處理可表示文本的流,并處理字符串的編碼和解碼。類 TextIOWrapper
繼承了 TextIOBase
,是原始緩沖流( BufferedIOBase
)的緩沖文本接口。最后, StringIO
是文本的內(nèi)存流。
參數(shù)名不是規(guī)范的一部分,只有 open()
的參數(shù)才用作關鍵字參數(shù)。
下表總結了抽象基類提供的 io
模塊:
抽象基類 |
繼承 |
抽象方法 |
Mixin方法和屬性 |
---|---|---|---|
|
|
||
|
繼承 |
||
|
繼承 |
||
|
繼承 |
I/O 基類?
- class io.IOBase?
The abstract base class for all I/O classes.
此類為許多方法提供了空的抽象實現(xiàn),派生類可以有選擇地重寫。默認實現(xiàn)代表一個無法讀取、寫入或查找的文件。
盡管
IOBase
沒有聲明read()
或write()
,因為它們的簽名會有所不同,但是實現(xiàn)和客戶端應該將這些方法視為接口的一部分。此外,當調(diào)用不支持的操作時可能會引發(fā)ValueError
(或UnsupportedOperation
)。從文件讀取或?qū)懭胛募亩M制數(shù)據(jù)的基本類型為
bytes
。其他 bytes-like objects 也可以作為方法參數(shù)。文本I/O類使用str
數(shù)據(jù)。請注意,在關閉的流上調(diào)用任何方法(甚至查詢)都是未定義的(undefined)。在這種情況下,實現(xiàn)可能會引發(fā)
ValueError
。IOBase
(及其子類)支持迭代器協(xié)議,這意味著可以迭代IOBase
對象以產(chǎn)生流中的行。根據(jù)流是二進制流(產(chǎn)生字節(jié))還是文本流(產(chǎn)生字符串),行的定義略有不同。請參見下面的readline()
。IOBase
也是一個上下文管理器,因此支持with
語句。 在這個示例中,file 將在with
語句塊執(zhí)行完成之后被關閉 --- 即使是發(fā)生了異常:with open('spam.txt', 'w') as file: file.write('Spam and eggs!')
IOBase
提供以下數(shù)據(jù)屬性和方法:- close()?
刷新并關閉此流。如果文件已經(jīng)關閉,則此方法無效。文件關閉后,對文件的任何操作(例如讀取或?qū)懭耄┒紩l(fā)
ValueError
。為方便起見,允許多次調(diào)用此方法。但是,只有第一個調(diào)用才會生效。
- closed?
如果流已關閉,則返回 True。
- flush()?
刷新流的寫入緩沖區(qū)(如果適用)。這對只讀和非阻塞流不起作用。
- isatty()?
如果流是交互式的(即連接到終端/tty設備),則返回
True
。
- readline(size=- 1, /)?
從流中讀取并返回一行。如果指定了 size,將至多讀取 size 個字節(jié)。
對于二進制文件行結束符總是
b'\n'
;對于文本文件,可以用將 newline 參數(shù)傳給open()
的方式來選擇要識別的行結束符。
- readlines(hint=- 1, /)?
從流中讀取并返回包含多行的列表。可以指定 hint 來控制要讀取的行數(shù):如果(以字節(jié)/字符數(shù)表示的)所有行的總大小超出了 hint 則將不會讀取更多的行。
0
或更小的 hint 值以及None
,會被視為沒有 hint。請注意使用
for line in file: ...
就足夠?qū)ξ募ο筮M行迭代了,可以不必調(diào)用file.readlines()
。
- seek(offset, whence=SEEK_SET, /)?
將流位置修改到給定的字節(jié) offset。 offset 將相對于由 whence 指定的位置進行解析。 whence 的默認值為
SEEK_SET
。 whence 的可用值有:SEEK_SET
或0
-- 流的開頭(默認值);offset 應為零或正值SEEK_CUR
or1
-- 當前流位置;offset 可以為負值SEEK_END
or2
-- 流的末尾;offset 通常為負值
返回新的絕對位置。
3.1 新版功能:
SEEK_*
常量.3.3 新版功能: 某些操作系統(tǒng)還可支持其他的值,例如
os.SEEK_HOLE
或os.SEEK_DATA
。特定文件的可用值還會取決于它是以文本還是二進制模式打開。
- seekable()?
如果流支持隨機訪問則返回
True
。 如為False
,則seek()
,tell()
和truncate()
將引發(fā)OSError
。
- tell()?
返回當前流的位置。
- truncate(size=None, /)?
將流的大小調(diào)整為給定的 size 個字節(jié)(如果未指定 size 則調(diào)整至當前位置)。 當前的流位置不變。 這個調(diào)整操作可擴展或減小當前文件大小。 在擴展的情況下,新文件區(qū)域的內(nèi)容取決于具體平臺(在大多數(shù)系統(tǒng)上,額外的字節(jié)會填充為零)。 返回新的文件大小。
在 3.5 版更改: 現(xiàn)在Windows在擴展時將文件填充為零。
- writable()?
如果流支持寫入則返回
True
。 如為False
,則write()
和truncate()
將引發(fā)OSError
。
- writelines(lines, /)?
將行列表寫入到流。 不會添加行分隔符,因此通常所提供的每一行都帶有末尾行分隔符。
- class io.RawIOBase?
Base class for raw binary streams. It inherits
IOBase
.原始二進制流通常會提供對下層 OS 設備或 API 的低層級訪問,而不是嘗試將其封裝到高層級的基元中(此功能是在更高層級的緩沖二進制流和文本流中實現(xiàn)的,將在下文中描述)。
RawIOBase
在IOBase
的現(xiàn)有成員以外還提供了下列方法:- read(size=- 1, /)?
從對象中讀取 size 個字節(jié)并將其返回。 作為一個便捷選項,如果 size 未指定或為 -1,則返回所有字節(jié)直到 EOF。 在其他情況下,僅會執(zhí)行一次系統(tǒng)調(diào)用。 如果操作系統(tǒng)調(diào)用返回字節(jié)數(shù)少于 size 則此方法也可能返回少于 size 個字節(jié)。
如果返回 0 個字節(jié)而 size 不為零 0,這表明到達文件末尾。 如果處于非阻塞模式并且沒有更多字節(jié)可用,則返回
None
。默認實現(xiàn)會轉至
readall()
和readinto()
。
- readall()?
從流中讀取并返回所有字節(jié)直到 EOF,如有必要將對流執(zhí)行多次調(diào)用。
- readinto(b, /)?
將字節(jié)數(shù)據(jù)讀入預先分配的可寫 bytes-like object b,并返回所讀取的字節(jié)數(shù)。 例如,b 可以是一個
bytearray
。 如果對象處理非阻塞模式并且沒有更多字節(jié)可用,則返回None
。
- write(b, /)?
將給定的 bytes-like object b 寫入到下層的原始流,并返回所寫入的字節(jié)數(shù)。 這可以少于 b 的總字節(jié)數(shù),具體取決于下層原始流的設定,特別是如果它處于非阻塞模式的話。 如果原始流設為非阻塞并且不能真正向其寫入單個字節(jié)時則返回
None
。 調(diào)用者可以在此方法返回后釋放或改變 b,因此該實現(xiàn)應該僅在方法調(diào)用期間訪問 b。
- class io.BufferedIOBase?
Base class for binary streams that support some kind of buffering. It inherits
IOBase
.與
RawIOBase
的主要差別在于read()
,readinto()
和write()
等方法將(分別)嘗試按照要求讀取盡可能多的輸入或是耗盡所有給定的輸出,其代價是可能會執(zhí)行一次以上的系統(tǒng)調(diào)用。除此之外,那些方法還可能引發(fā)
BlockingIOError
,如果下層的原始數(shù)據(jù)流處于非阻塞模式并且無法接受或給出足夠數(shù)據(jù)的話;不同于對應的RawIOBase
方法,它們將永遠不會返回None
。并且,
read()
方法也沒有轉向readinto()
的默認實現(xiàn)。典型的
BufferedIOBase
實現(xiàn)不應當繼承自RawIOBase
實現(xiàn),而要包裝一個該實現(xiàn),正如BufferedWriter
和BufferedReader
所做的那樣。BufferedIOBase
在IOBase
的現(xiàn)有成員以外還提供或重載了下列數(shù)據(jù)屬性和方法:- raw?
由
BufferedIOBase
處理的下層原始流 (RawIOBase
的實例)。 它不是BufferedIOBase
API 的組成部分并且不存在于某些實現(xiàn)中。
- detach()?
從緩沖區(qū)分離出下層原始流并將其返回。
在原始流被分離之后,緩沖區(qū)將處于不可用的狀態(tài)。
某些緩沖區(qū)例如
BytesIO
并無可從此方法返回的單獨原始流的概念。 它們將會引發(fā)UnsupportedOperation
。3.1 新版功能.
- read(size=- 1, /)?
讀取并返回最多 size 個字節(jié)。 如果此參數(shù)被省略、為
None
或為負值,則讀取并返回所有數(shù)據(jù)直到 EOF。 如果流已經(jīng)到達 EOF 則返回一個空的bytes
對象。如果此參數(shù)為正值,并且下層原始流不可交互,則可能發(fā)起多個原始讀取以滿足字節(jié)計數(shù)(直至先遇到 EOF)。 但對于可交互原始流,則將至多發(fā)起一個原始讀取,并且簡短的結果并不意味著已到達 EOF。
BlockingIOError
會在下層原始流不處于阻塞模式,并且當前沒有可用數(shù)據(jù)時被引發(fā)。
- read1(size=- 1, /)?
通過至多一次對下層流的
read()
(或readinto()
) 方法的調(diào)用讀取并返回至多 size 個字節(jié)。 這適用于在BufferedIOBase
對象之上實現(xiàn)你自己的緩沖區(qū)的情況。如果 size 為
-1
(默認值),則返回任意數(shù)量的字節(jié)(多于零字節(jié),除非已到達 EOF)。
- readinto(b, /)?
將字節(jié)數(shù)據(jù)讀入預先分配的可寫 bytes-like object b 并返回所讀取的字節(jié)數(shù)。 例如,b 可以是一個
bytearray
。類似于
read()
,可能對下層原始流發(fā)起多次讀取,除非后者為交互式。BlockingIOError
會在下層原始流不處于阻塞模式,并且當前沒有可用數(shù)據(jù)時被引發(fā)。
- readinto1(b, /)?
將字節(jié)數(shù)據(jù)讀入預先分配的可寫 bytes-like object b,其中至多使用一次對下層原始流
read()
(或readinto()
) 方法的調(diào)用。 返回所讀取的字節(jié)數(shù)。BlockingIOError
會在下層原始流不處于阻塞模式,并且當前沒有可用數(shù)據(jù)時被引發(fā)。3.5 新版功能.
- write(b, /)?
寫入給定的 bytes-like object b,并返回寫入的字節(jié)數(shù) (總是等于 b 的字節(jié)長度,因為如果寫入失敗則會引發(fā)
OSError
)。 根據(jù)具體實現(xiàn)的不同,這些字節(jié)可能被實際寫入下層流,或是出于運行效率和冗余等考慮而暫存于緩沖區(qū)。當處于非阻塞模式時,如果需要將數(shù)據(jù)寫入原始流但它無法在不阻塞的情況下接受所有數(shù)據(jù)則將引發(fā)
BlockingIOError
。調(diào)用者可能會在此方法返回后釋放或改變 b,因此該實現(xiàn)應當僅在方法調(diào)用期間訪問 b。
原始文件 I/O?
- class io.FileIO(name, mode='r', closefd=True, opener=None)?
代表一個包含字節(jié)數(shù)據(jù)的 OS 層級文件的原始二進制流。 它繼承自
RawIOBase
。name 可以是以下兩項之一:
代表將被打開的文件路徑的字符串或
bytes
對象。 在此情況下 closefd 必須為True
(默認值) 否則將會引發(fā)異常。代表一個現(xiàn)有 OS 層級文件描述符的號碼的整數(shù),作為結果的
FileIO
對象將可訪問該文件。 當 FileIO 對象被關閉時此 fd 也將被關閉,除非 closefd 設為False
。
mode 可以為
'r'
,'w'
,'x'
或'a'
分別表示讀?。J模式)、寫入、獨占新建或添加。 如果以寫入或添加模式打開的文件不存在將自動新建;當以寫入模式打開時文件將先清空。 以新建模式打開時如果文件已存在則將引發(fā)FileExistsError
。 以新建模式打開文件也意味著要寫入,因此該模式的行為與'w'
類似。 在模式中附帶'+'
將允許同時讀取和寫入。該類的
read()
(當附帶正值參數(shù)調(diào)用時),readinto()
和write()
方法將只執(zhí)行一次系統(tǒng)調(diào)用。可以通過傳入一個可調(diào)用對象作為 opener 來使用自定義文件打開器。 然后通過調(diào)用 opener 并傳入 (name, flags) 來獲取文件對象所對應的下層文件描述符。 opener 必須返回一個打開文件描述符(傳入
os.open
作為 opener 的結果在功能上將與傳入None
類似)。新創(chuàng)建的文件是 不可繼承的。
有關 opener 參數(shù)的示例,請參見內(nèi)置函數(shù)
open()
。在 3.3 版更改: 增加了 opener 參數(shù)。增加了
'x'
模式。在 3.4 版更改: 文件現(xiàn)在禁止繼承。
FileIO
在繼承自RawIOBase
和IOBase
的現(xiàn)有成員以外還提供了以下數(shù)據(jù)屬性和方法:- mode?
構造函數(shù)中給定的模式。
- name?
文件名。當構造函數(shù)中沒有給定名稱時,這是文件的文件描述符。
緩沖流?
相比原始 I/O,緩沖 I/O 流提供了針對 I/O 設備的更高層級接口。
- class io.BytesIO(initial_bytes=b'')?
一個使用內(nèi)在字節(jié)緩沖區(qū)的二進制流。 它繼承自
BufferedIOBase
。 在close()
方法被調(diào)用時將會丟棄緩沖區(qū)。可選參數(shù) initial_bytes 是一個包含初始數(shù)據(jù)的 bytes-like object。
BytesIO
在繼承自BufferedIOBase
和IOBase
的成員以外還提供或重載了下列方法:- getbuffer()?
返回一個對應于緩沖區(qū)內(nèi)容的可讀寫視圖而不必拷貝其數(shù)據(jù)。 此外,改變視圖將透明地更新緩沖區(qū)內(nèi)容:
>>> 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
。當從此對象讀取數(shù)據(jù)時,可能會從下層原始流請求更大量的數(shù)據(jù),并存放到內(nèi)部緩沖區(qū)中。 接下來可以在后續(xù)讀取時直接返回緩沖數(shù)據(jù)。
根據(jù)給定的可讀 raw 流和 buffer_size 創(chuàng)建
BufferedReader
的構造器。 如果省略 buffer_size,則會使用DEFAULT_BUFFER_SIZE
。BufferedReader
在繼承自BufferedIOBase
和IOBase
的成員以外還提供或重載了下列方法:- peek(size=0, /)?
從流返回字節(jié)數(shù)據(jù)而不前移位置。 完成此調(diào)用將至多讀取一次原始流。 返回的字節(jié)數(shù)量可能少于或多于請求的數(shù)量。
- read(size=- 1, /)?
讀取并返回 size 個字節(jié),如果 size 未給定或為負值,則讀取至 EOF 或是在非阻塞模式下讀取調(diào)用將會阻塞。
- read1(size=- 1, /)?
在原始流上通過單次調(diào)用讀取并返回至多 size 個字節(jié)。 如果至少緩沖了一個字節(jié),則只返回緩沖的字節(jié)。 在其他情況下,將執(zhí)行一次原始流讀取。
在 3.7 版更改: size 參數(shù)現(xiàn)在是可選的。
- class io.BufferedWriter(raw, buffer_size=DEFAULT_BUFFER_SIZE)?
一個提供對可寫、不可查找的
RawIOBase
原始二進制流的高層級訪問的緩沖二進制流。 它繼承自BufferedIOBase
。當寫入到此對象時,數(shù)據(jù)通常會被放入到內(nèi)部緩沖區(qū)中。 緩沖區(qū)將在滿足某些條件的情況下被寫到下層的
RawIOBase
對象,包括:當緩沖區(qū)對于所有掛起數(shù)據(jù)而言太小時;
當
flush()
被調(diào)用時當(為
BufferedRandom
對象)請求seek()
時;當
BufferedWriter
對象被關閉或銷毀時。
該構造器會為給定的可寫 raw 流創(chuàng)建一個
BufferedWriter
。 如果未給定 buffer_size,則使用默認的DEFAULT_BUFFER_SIZE
。BufferedWriter
在繼承自BufferedIOBase
和IOBase
的成員以外還提供或重載了下列方法:- flush()?
將緩沖區(qū)中保存的字節(jié)數(shù)據(jù)強制放入原始流。 如果原始流發(fā)生阻塞則應當引發(fā)
BlockingIOError
。
- write(b, /)?
寫入 bytes-like object b 并返回寫入的字節(jié)數(shù)。 當處于非阻塞模式時,如果緩沖區(qū)需要被寫入但原始流發(fā)生阻塞則將引發(fā)
BlockingIOError
。
- class io.BufferedRandom(raw, buffer_size=DEFAULT_BUFFER_SIZE)?
一個提供對不可查找的
RawIOBase
原始二進制流的高層級訪問的緩沖二進制流。 它繼承自BufferedReader
和BufferedWriter
。該構造器會為在第一個參數(shù)中給定的可查找原始流創(chuàng)建一個讀取器和寫入器。 如果省略 buffer_size 則使用默認的
DEFAULT_BUFFER_SIZE
。BufferedRandom
能做到BufferedReader
或BufferedWriter
所能做的任何事。 此外,還會確保實現(xiàn)seek()
和tell()
。
- class io.BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /)?
一個提供對兩個不可查找的
RawIOBase
原始二進制流的高層級訪問的緩沖二進制流 --- 一個可讀,另一個可寫。 它繼承自BufferedIOBase
。reader 和 writer 分別是可讀和可寫的
RawIOBase
對象。 如果省略 buffer_size 則使用默認的DEFAULT_BUFFER_SIZE
。BufferedRWPair
實現(xiàn)了BufferedIOBase
的所有方法,但detach()
除外,調(diào)用該方法將引發(fā)UnsupportedOperation
。警告
BufferedRWPair
不會嘗試同步訪問其下層的原始流。 你不應當將傳給它與讀取器和寫入器相同的對象;而要改用BufferedRandom
。
文本 I/O?
- class io.TextIOBase?
Base class for text streams. This class provides a character and line based interface to stream I/O. It inherits
IOBase
.TextIOBase
在來自IOBase
的成員以外還提供或重載了以下數(shù)據(jù)屬性和方法:- encoding?
用于將流的字節(jié)串解碼為字符串以及將字符串編碼為字節(jié)串的編碼格式名稱。
- errors?
解碼器或編碼器的錯誤設置。
- newlines?
一個字符串、字符串元組或者
None
,表示目前已經(jīng)轉寫的新行。 根據(jù)具體實現(xiàn)和初始構造器旗標的不同,此屬性或許會不可用。
- buffer?
由
TextIOBase
處理的下層二進制緩沖區(qū)(為一個BufferedIOBase
的實例)。 它不是TextIOBase
API 的組成部分并且不存在于某些實現(xiàn)中。
- detach()?
從
TextIOBase
分離出下層二進制緩沖區(qū)并將其返回。在下層緩沖區(qū)被分離后,
TextIOBase
將處于不可用的狀態(tài)。某些
TextIOBase
的實現(xiàn),例如StringIO
可能并無下層緩沖區(qū)的概念,因此調(diào)用此方法將引發(fā)UnsupportedOperation
。3.1 新版功能.
- readline(size=- 1, /)?
讀取至換行符或 EOF 并返回單個
str
。 如果流已經(jīng)到達 EOF,則將返回一個空字符串。如果指定了 size ,最多將讀取 size 個字符。
- seek(offset, whence=SEEK_SET, /)?
將流位置改為給定的偏移位置 offset。 具體行為取決于 whence 形參。 whence 的默認值為
SEEK_SET
。SEEK_SET
或0
: 從流的開始位置起查找(默認值);offset 必須為TextIOBase.tell()
所返回的數(shù)值或為零。 任何其他 offset 值都將導致未定義的行為。SEEK_CUR
或1
: "查找" 到當前位置;offset 必須為零,表示無操作(所有其他值均不受支持)。SEEK_END
或2
: 查找到流的末尾;offset 必須為零(所有其他值均不受支持)。
以不透明數(shù)字形式返回新的絕對位置。
3.1 新版功能:
SEEK_*
常量.
- tell()?
以不透明數(shù)字形式返回當前流的位置。 該數(shù)字通常并不代表下層二進制存儲中對應的字節(jié)數(shù)。
- write(s, /)?
將字符串 s 寫入到流并返回寫入的字符數(shù)。
- class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False, write_through=False)?
一個提供對
BufferedIOBase
緩沖二進制流的高層級訪問的緩沖文本流。 它繼承自TextIOBase
。encoding gives the name of the encoding that the stream will be decoded or encoded with. It defaults to
locale.getencoding()
.encoding="locale"
can be used to specify the current locale's encoding explicitly. See 文本編碼格式 for more information.errors 是一個可選的字符串,它指明編碼格式和編碼格式錯誤的處理方式。 傳入
'strict'
將在出現(xiàn)編碼格式錯誤時引發(fā)ValueError
(默認值None
具有相同的效果),傳入'ignore'
將忽略錯誤。 (請注意忽略編碼格式錯誤會導致數(shù)據(jù)丟失。)'replace'
會在出現(xiàn)錯誤數(shù)據(jù)時插入一個替換標記 (例如'?'
)。'backslashreplace'
將把錯誤數(shù)據(jù)替換為一個反斜杠轉義序列。 在寫入時,還可以使用'xmlcharrefreplace'
(替換為適當?shù)?XML 字符引用) 或'namereplace'
(替換為\N{...}
轉義序列)。 任何其他通過codecs.register_error()
注冊的錯誤處理方式名稱也可以被接受。newline 控制行結束符處理方式。 它可以為
None
,''
,'\n'
,'\r'
和'\r\n'
。 其工作原理如下:當從流讀取輸入時,如果 newline 為
None
,則將啟用 universal newlines 模式。 輸入中的行結束符可以為'\n'
,'\r'
或'\r\n'
,在返回給調(diào)用者之前它們會被統(tǒng)一轉寫為'\n'
。 如果 newline 為''
,也會啟用通用換行模式,但行結束符會不加轉寫即返回給調(diào)用者。 如果 newline 具有任何其他合法的值,則輸入行將僅由給定的字符串結束,并且行結束符會不加轉寫即返回給調(diào)用者。將輸出寫入流時,如果 newline 為
None
,則寫入的任何'\n'
字符都將轉換為系統(tǒng)默認行分隔符os.linesep
。如果 newline 是''
或'\n'
,則不進行翻譯。如果 newline 是任何其他合法值,則寫入的任何'\n'
字符將被轉換為給定的字符串。
如果 line_buffering 為
True
,則當一個寫入調(diào)用包含換行符或回車時將會應用flush()
。如果 write_through 為
True
,對write()
的調(diào)用會確保不被緩沖:在TextIOWrapper
對象上寫入的任何數(shù)據(jù)會立即交給其下層的 buffer 來處理。在 3.3 版更改: 已添加 write_through 參數(shù)
在 3.3 版更改: 默認的 encoding 現(xiàn)在將為
locale.getpreferredencoding(False)
而非locale.getpreferredencoding()
。 不要使用locale.setlocale()
來臨時改變區(qū)域編碼格式,要使用當前區(qū)域編碼格式而不是用戶的首選編碼格式。在 3.10 版更改: encoding 參數(shù)現(xiàn)在支持
"locale"
作為編碼格式名稱。TextIOWrapper
在繼承自TextIOBase
和IOBase
的現(xiàn)有成員以外還提供了以下數(shù)據(jù)屬性和方法:- line_buffering?
是否啟用行緩沖。
- write_through?
寫入是否要立即傳給下層的二進制緩沖。
3.7 新版功能.
- reconfigure(*[, encoding][, errors][, newline][, line_buffering][, write_through])?
使用 encoding, errors, newline, line_buffering 和 write_through 的新設置來重新配置此文本流。
未指定的形參將保留當前設定,例外情況是當指定了 encoding 但未指定 errors 時將會使用
errors='strict'
。如果已經(jīng)有數(shù)據(jù)從流中被讀取則將無法再改變編碼格式或行結束符。 另一方面,在寫入數(shù)據(jù)之后再改變編碼格式則是可以的。
此方法會在設置新的形參之前執(zhí)行隱式的流刷新。
3.7 新版功能.
在 3.11 版更改: The method supports
encoding="locale"
option.
- class io.StringIO(initial_value='', newline='\n')?
一個使用內(nèi)存文本緩沖的文本流。 它繼承自
TextIOBase
。當
close()
方法被調(diào)用時將會丟棄文本緩沖區(qū)。緩沖區(qū)的初始值可通過提供 initial_value 來設置。 如果啟用了行結束符轉寫,換行將以
write()
所用的方式被編碼。 數(shù)據(jù)流位置將被設為緩沖區(qū)的開頭。newline 參數(shù)的規(guī)則與
TextIOWrapper
所用的一致,不同之處在于當將輸出寫入到流時,如果 newline 為None
,則在所有平臺上換行符都會被寫入為\n
。StringIO
在繼承自TextIOBase
和IOBase
的現(xiàn)有成員以外還提供了以下方法:用法示例:
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
。
性能?
本節(jié)討論所提供的具體 I/O 實現(xiàn)的性能。
二進制 I/O?
即使在用戶請求單個字節(jié)時,也只讀取和寫入大塊數(shù)據(jù)。通過該方法,緩沖 I/O 隱藏了操作系統(tǒng)調(diào)用和執(zhí)行無緩沖 I/O 例程時的任何低效性。增益取決于操作系統(tǒng)和執(zhí)行的 I/O 類型。例如,在某些現(xiàn)代操作系統(tǒng)上(例如 Linux),無緩沖磁盤 I/O 可以與緩沖 I/O 一樣快。但最重要的是,無論平臺和支持設備如何,緩沖 I/O 都能提供可預測的性能。因此,對于二進制數(shù)據(jù),應首選使用緩沖的 I/O 而不是未緩沖的 I/O 。
文本 I/O?
二進制存儲(如文件)上的文本 I/O 比同一存儲上的二進制 I/O 慢得多,因為它需要使用字符編解碼器在Unicode和二進制數(shù)據(jù)之間進行轉換。這在處理大量文本數(shù)據(jù)(如大型日志文件)時會變得非常明顯。此外,由于使用的重構算法 TextIOWrapper.tell()
和 TextIOWrapper.seek()
都相當慢。
多線程?
FileIO
對象是線程安全的,只要它們封裝的操作系統(tǒng)調(diào)用(比如Unix下的 read(2)
)也是線程安全的。
二進制緩沖對象(例如 BufferedReader
, BufferedWriter
, BufferedRandom
和 BufferedRWPair
)使用鎖來保護其內(nèi)部結構;因此,可以安全地一次從多個線程中調(diào)用它們。
TextIOWrapper
對象不再是線程安全的。
可重入性?
二進制緩沖對象( BufferedReader
, BufferedWriter
, BufferedRandom
和 BufferedRWPair
的實例)不是可重入的。雖然在正常情況下不會發(fā)生可重入調(diào)用,但仍可能會在 signal
處理程序執(zhí)行 I/O 時產(chǎn)生。如果線程嘗試重入已經(jīng)訪問的緩沖對象,則會引發(fā) RuntimeError
。注意,這并不禁止其他線程進入緩沖對象。
上面的內(nèi)容隱式地擴展到文本文件中,因為 open()
函數(shù)將把緩沖對象封裝在 TextIOWrapper
中。 這包括標準流,因而也會影響內(nèi)置的 print()
函數(shù)。