檢視原始碼 io (stdlib v6.2)
標準 I/O 伺服器介面函數。
此模組提供與標準 Erlang I/O 伺服器的介面。如果輸出函數成功,它們都會返回 ok
,否則會退出。
此模組中的所有函數都有一個可選參數 IoDevice
。 如果包含,它必須是處理 I/O 協議的進程的 PID。 通常,它是由 file:open/2
返回的 IoDevice
。 如果沒有給定 IoDevice
,則使用 standard_io
。
有關 I/O 協議的描述,請參閱使用者指南中的Erlang I/O 協議 章節。
警告
提供給函數
put_chars/2
的數據應為unicode:chardata/0
格式。 這表示將二進制數據提供給此函數的程式必須先將它們轉換為 UTF-8,然後才能嘗試在 I/O 裝置上輸出數據。如果 I/O 裝置設定為二進制模式,函數
get_chars/2,3
和get_line/1,2
可以返回二進制數據而不是列表。 這些二進制數據以 UTF-8 編碼。若要使用 ISO Latin-1 編碼的二進制數據,請改用
file
模組。有關字元編碼之間的轉換函數,請參閱
unicode
模組。
錯誤資訊
此模組中提到的 ErrorInfo
是從所有 I/O 模組返回的標準 ErrorInfo
結構。 其格式如下:
{ErrorLocation, Module, ErrorDescriptor}
透過以下呼叫可取得描述錯誤的字串:
Module:format_error(ErrorDescriptor)
摘要
類型
I/O 裝置,可以是 standard_io/0
、standard_error/0
、user/0
、file:io_server/0
、註冊名稱,或任何處理 I/O 協議的 PID。
當沒有數據時,I/O 伺服器會發送的內容。
I/O 裝置 standard_error
可用於將輸出導向到目前作業系統認為適合錯誤輸出的 I/O 裝置。 當標準輸出被重新導向時,這會很有用。
指派給進程的預設標準 I/O 裝置。當此模組中的函數呼叫中沒有指定 IoDevice
參數時,會使用此裝置。
可用於與節點本機 stdout
和 stdin
互動的 I/O 裝置。 這可以是終端機、管道、檔案或組合。
函數
擷取 IoDevice
的欄數(即終端機的寬度)。
從 IoDevice
讀取字元,並以 Prompt
提示。 根據 Format
解釋字元。
根據 Format
將 Data
中的項目寫入 IoDevice
。
從 IoDevice
讀取 Count
個字元,並以 Prompt
提示。
從 IoDevice
讀取一行,並以 Prompt
提示。
請求 IoDevice
的所有可用選項及其目前值。
等同於 nl(standard_io)
。
將新行寫入標準輸出 (IoDevice
)。
從 IoDevice
讀取數據,並以 Prompt
提示。
從 IoDevice
讀取數據,並以 Prompt
提示。
傳回使用者要求的可列印 Unicode 字元範圍。
將 CharData
的字元寫入 IoDevice
。
從標準輸入 (IoDevice
) 讀取一個詞條 Term
,並以 Prompt
提示。
從 IoDevice
讀取一個詞條 Term
,並以 Prompt
提示。
等同於 rows(standard_io)
。
擷取 IoDevice
的列數(即終端機的高度)。
從 IoDevice
讀取數據,並以 Prompt
提示。
從 IoDevice
讀取數據,並以 Prompt
提示。
設定 IoDevice
的選項。 可用的選項和值因 I/O 裝置而異。
將詞條 Term
寫入 IoDevice
。
類型
-type device() :: atom() | pid() | file:io_server() | standard_io() | standard_error() | user().
I/O 裝置,可以是 standard_io/0
、standard_error/0
、user/0
、file:io_server/0
、註冊名稱,或任何處理 I/O 協議的 PID。
-type encoding() ::
latin1 | unicode | utf8 | utf16 | utf32 | {utf16, big | little} | {utf32, big | little}.
-type parse_form_ret() :: {ok, AbsForm :: erl_parse:abstract_form(), EndLocation :: erl_anno:location()} | {eof, EndLocation :: erl_anno:location()} | {error, ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(), ErrorLocation :: erl_anno:location()} | server_no_data().
-type parse_ret() :: {ok, ExprList :: [erl_parse:abstract_expr()], EndLocation :: erl_anno:location()} | {eof, EndLocation :: erl_anno:location()} | {error, ErrorInfo :: erl_scan:error_info() | erl_parse:error_info(), ErrorLocation :: erl_anno:location()} | server_no_data().
-type prompt() :: atom() | unicode:chardata().
-type server_no_data() :: {error, ErrorDescription :: term()} | eof.
當沒有數據時,I/O 伺服器會發送的內容。
-type setopt() :: binary | list | option().
-type standard_error() :: standard_error.
I/O 裝置 standard_error
可用於將輸出導向到目前作業系統認為適合錯誤輸出的 I/O 裝置。 當標準輸出被重新導向時,這會很有用。
在類 Unix 作業系統上的範例
$ erl -noinput -eval 'io:format(standard_error,"Error: ~s~n",["error 11"]),'\
'init:stop().' > /dev/null
Error: error 11
-type standard_io() :: standard_io.
指派給進程的預設標準 I/O 裝置。當此模組中的函數呼叫中沒有指定 IoDevice
參數時,會使用此裝置。
有時需要使用明確的 IoDevice
引數來參照預設的 I/O 裝置。當函數可以存取檔案或預設 I/O 裝置時,就會出現這種情況。原子 standard_io
具有這種特殊含義。以下範例說明了這一點
27> io:read('enter>').
enter>foo.
{ok,foo}
28> io:read(standard_io, 'enter>').
enter>bar.
{ok,bar}
預設情況下,所有傳送到 standard_io
的 I/O 都會最終導向產生呼叫進程的節點的 user
I/O 裝置。
standard_io
是 group_leader/0
的別名,因此為了變更預設輸入/輸出請求的傳送位置,您可以使用 group_leader(NewGroupLeader, self())
來變更目前進程的群組領導者。
-type user() :: user.
可用於與節點本機 stdout
和 stdin
互動的 I/O 裝置。 這可以是終端機、管道、檔案或組合。
使用 getopts/1
來取得有關 I/O 裝置的更多資訊。
請參閱 Erlang 使用者指南中的 互動式 Shell 和 Escripts 和非互動式 I/O,以了解有關 user
如何處理 Unicode 的詳細資訊。
函數
-spec columns() -> {ok, pos_integer()} | {error, enotsup}.
等同於 columns(standard_io)
。
-spec columns(IoDevice) -> {ok, pos_integer()} | {error, enotsup} when IoDevice :: device().
擷取 IoDevice
的欄數(即終端機的寬度)。
此函數在終端裝置上執行成功,並對所有其他 I/O 裝置傳回 {error, enotsup}
。
-spec format(Format) -> ok when Format :: format().
等同於 format(Format, [])
。
-spec fread(IoDevice, Prompt, Format) -> Result when IoDevice :: device(), Prompt :: prompt(), Format :: format(), Result :: {ok, Terms :: [term()]} | {error, {fread, FreadError :: io_lib:fread_error()}} | server_no_data().
從 IoDevice
讀取字元,並以 Prompt
提示。 根據 Format
解釋字元。
Format
可以包含以下內容
- 空白字元 (空格、Tab 和換行符號) 會導致讀取輸入直到下一個非空白字元。
- 必須與下一個輸入字元比對的一般字元。
- 控制序列,其一般格式為
~*FMC
,其中- 字元
*
是一個可選的傳回抑制字元。它提供一種方法來指定要省略的欄位。 F
是輸入欄位的欄位寬度
。M
是一個可選的轉換修飾符 (其中t
是唯一支援的,表示 Unicode 轉換)。C
決定控制序列的類型。
~
- 輸入中預期會有單一的~
。d
- 預期會有十進位整數。u
- 預期會有 2-36 進位中的無符號整數。欄位寬度參數用於指定進位。不略過前導空白字元。-
- 預期會有可選的正負號字元。正負號字元-
會傳回值-1
。正負號字元+
或無符號會傳回1
。忽略欄位寬度參數。不略過前導空白字元。#
- 預期會有具有 Erlang 樣式進位前綴 (例如,"16#ffff"
) 的 2-36 進位整數。f
- 預期會有浮點數。它必須遵循 Erlang 浮點數語法。s
- 讀取非空白字元的字串。如果已指定欄位寬度,則會讀取此數量的字元,並移除所有尾隨空白字元。會傳回 Erlang 字串 (字元清單)。如果 Unicode 轉換生效 (
~ts
),則會接受字元 > 255,否則不接受。使用轉換修飾符,傳回的清單也可能會因此包含大於 255 的整數1> io:fread("Prompt> ","~s"). Prompt> <Characters beyond latin1 range not printable in this medium> {error,{fread,string}} 2> io:fread("Prompt> ","~ts"). Prompt> <Characters beyond latin1 range not printable in this medium> {ok,[[1091,1085,1080,1094,1086,1076,1077]]}
a
- 與s
類似,但結果字串會轉換為原子。c
- 讀取與欄位寬度相等的字元數 (預設值為 1),並以 Erlang 字串的形式傳回。但是,不會像使用s
那樣省略前導和尾隨空白字元。會傳回所有字元。Unicode 轉換修飾符的工作方式與
s
相同1> io:fread("Prompt> ","~c"). Prompt> <Character beyond latin1 range not printable in this medium> {error,{fread,string}} 2> io:fread("Prompt> ","~tc"). Prompt> <Character beyond latin1 range not printable in this medium> {ok,[[1091]]}
l
- 傳回已掃描到該點的字元數,包括空白字元。
{ok, Terms}
- 讀取成功,且Terms
是成功比對和讀取項目的清單。eof
- 遇到檔案結尾。{error, FreadError}
- 讀取失敗,且FreadError
會提供有關錯誤的提示。{error, ErrorDescription}
- 讀取作業失敗,且參數ErrorDescription
會提供有關錯誤的提示。
- 字元
範例
20> io:fread('enter>', "~f~f~f").
enter>1.9 35.5e3 15.0
{ok,[1.9,3.55e4,15.0]}
21> io:fread('enter>', "~10f~d").
enter> 5.67899
{ok,[5.678,99]}
22> io:fread('enter>', ":~10s:~10c:").
enter>: alan : joe :
{ok, ["alan", " joe "]}
-spec fwrite(Format) -> ok when Format :: format().
等同於 fwrite(Format, [])
。
-spec fwrite(IoDevice, Format, Data) -> ok when IoDevice :: device(), Format :: format(), Data :: [term()].
根據 Format
將 Data
中的項目寫入 IoDevice
。
Format
包含複製到輸出裝置的一般字元,以及用於格式化的控制序列,請參閱下文。如果 Format
是原子或二進位,則會先使用 atom_to_list/1
或 binary_to_list/1
將其轉換為清單。範例
1> io:fwrite("Hello world!~n", []).
Hello world!
ok
控制序列的一般格式為 ~F.P.PadModC
。
字元 C
決定要使用的控制序列類型。它是唯一需要的欄位。F
、P
、Pad
和 Mod
都是可選的。例如,若要將 #
用於 Pad
但使用 F
和 P
的預設值,您可以寫入 ~..#C
。
F
是列印引數的欄位寬度
。負值表示引數在欄位內向左對齊,否則為向右對齊。如果未指定欄位寬度,則會使用所需的列印寬度。如果指定的欄位寬度太小,則整個欄位會填入*
字元。P
是列印引數的精確度
。如果未指定精確度,則會使用預設值。精確度的解譯取決於控制序列。除非另有說明,否則引數within
用於決定列印寬度。Pad
是填補字元。這是用來填補引數的列印表示法的字元,以便符合指定的欄位寬度和精確度。只能指定一個填補字元,並且在適用時,它會同時用於欄位寬度和精確度。預設的填補字元為' '
(空格)。Mod
是控制序列修飾符。這是一個或多個會變更Data
解譯的字元。目前的修飾符為
t
- 用於 Unicode 轉換。l
- 用於停止p
和P
偵測可列印字元。k
- 用於p
、P
、w
和W
,以在 map 金鑰ordered
順序中格式化 map (請參閱maps:iterator_order/0
)。K
- 與k
類似,用於以 map 金鑰順序格式化 map,但會採用額外的引數,指定maps:iterator_order/0
。例如
> M = #{ a => 1, b => 2 }. #{a => 1,b => 2} > io:format("~Kp~n", [reversed, M]). #{b => 2,a => 1} ok
如果 F
、P
或 Pad
是 *
字元,則 Data
中的下一個引數會用作值。例如
1> io:fwrite("~*.*.0f~n",[9, 5, 3.14159265]).
003.14159
ok
若要將常值 *
字元當作 Pad
使用,則必須將其當作引數傳遞
2> io:fwrite("~*.*.*f~n",[9, 5, $*, 3.14159265]).
**3.14159
ok
可用的控制序列
~
- 寫入字元~
。c
- 引數是一個數字,會解譯為 ASCII 代碼。精確度是列印字元的次數,預設值為欄位寬度,而欄位寬度又預設為 1。範例1> io:fwrite("|~10.5c|~-10.5c|~5c|~n", [$a, $b, $c]). | aaaaa|bbbbb |ccccc| ok
如果 Unicode 轉換修飾符 (
t
) 生效,則整數引數可以是表示有效 Unicode 字碼點的任何數字,否則它必須是小於或等於 255 的整數,否則會使用 16#FF 遮罩。2> io:fwrite("~tc~n",[1024]). \x{400} ok 3> io:fwrite("~c~n",[1024]). ^@ ok
f
- 引數是一個浮點數,會寫入為[-]ddd.ddd
,其中精確度是小數點後的位數。預設的精確度為 6,且不得 < 1。e
- 引數是一個浮點數,會寫入為[-]d.ddde+-ddd
,其中精確度是寫入的位數。預設的精確度為 6,且不得 < 2。g
- 引數是一個浮點數,如果它 >= 0.1 且 < 10000.0,則會寫入為f
。否則,會以e
格式寫入。精確度是有效位數。預設值為 6,且不得 < 2。如果浮點數的絕對值不允許以所需的有效位數的f
格式寫入,則也會以e
格式寫入。s
- 使用字串語法印出參數。如果沒有 Unicode 轉換修飾符,參數可以是iolist/0
、binary/0
或atom/0
。如果使用 Unicode 轉換修飾符 (t
),則參數為unicode:chardata()
,表示二進位資料為 UTF-8 編碼。字元會以不帶引號的方式印出。字串會先根據指定的精確度截斷,然後以指定的欄位寬度進行填充和對齊。預設的精確度為欄位寬度。此格式可用於印出任何物件,並截斷輸出以符合指定的欄位
1> io:fwrite("|~10w|~n", [{hey, hey, hey}]). |**********| ok 2> io:fwrite("|~10s|~n", [io_lib:write({hey, hey, hey})]). |{hey,hey,h| 3> io:fwrite("|~-10.8s|~n", [io_lib:write({hey, hey, hey})]). |{hey,hey | ok
如果未指定 Unicode 轉換修飾符,則包含大於 255 的整數的列表會被視為錯誤
4> io:fwrite("~ts~n",[[1024]]). \x{400} ok 5> io:fwrite("~s~n",[[1024]]). ** exception error: bad argument in function io:format/3 called as io:format(<0.53.0>,"~s~n",[[1024]])
w
- 使用標準語法寫入資料。這用於輸出 Erlang 詞彙。如果 atom 包含嵌入的非列印字元,則會使用引號括起來。除非使用 Unicode 轉換修飾符 (t
),否則大於 255 的 atom 字元會被跳脫。浮點數會以最短且正確四捨五入的字串精確印出。p
- 以與~w
相同的方式使用標準語法寫入資料,但會將印出的表示法長度超過一行的詞彙分成多行,並以合理的方式縮排每一行。不支援左對齊。它還會嘗試偵測可列印字元的平面列表,並將其輸出為字串。例如1> T = [{attributes,[[{id,age,1.50000},{mode,explicit}, {typename,"INTEGER"}], [{id,cho},{mode,explicit},{typename,'Cho'}]]}, {typename,'Person'},{tag,{'PRIVATE',3}},{mode,implicit}]. ... 2> io:fwrite("~w~n", [T]). [{attributes,[[{id,age,1.5},{mode,explicit},{typename, [73,78,84,69,71,69,82]}],[{id,cho},{mode,explicit},{typena me,'Cho'}]]},{typename,'Person'},{tag,{'PRIVATE',3}},{mode ,implicit}] ok 3> io:fwrite("~62p~n", [T]). [{attributes,[[{id,age,1.5}, {mode,explicit}, {typename,"INTEGER"}], [{id,cho},{mode,explicit},{typename,'Cho'}]]}, {typename,'Person'}, {tag,{'PRIVATE',3}}, {mode,implicit}] ok
欄位寬度指定最大行長度。預設值為 80。精確度指定詞彙的初始縮排。預設值為在同一個
write/1
或format/1,2,3
呼叫中,此行所印出的字元數。例如,使用上面的T
4> io:fwrite("Here T = ~62p~n", [T]). Here T = [{attributes,[[{id,age,1.5}, {mode,explicit}, {typename,"INTEGER"}], [{id,cho}, {mode,explicit}, {typename,'Cho'}]]}, {typename,'Person'}, {tag,{'PRIVATE',3}}, {mode,implicit}] ok
從 Erlang/OTP 21.0 開始,欄位寬度值
0
可用於指定行無限長,這表示不會插入換行符。例如5> io:fwrite("~0p~n", [lists:seq(1, 30)]). [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30] ok
當指定修飾符
l
時,不會偵測可列印字元列表,例如6> S = [{a,"a"}, {b, "b"}], io:fwrite("~15p~n", [S]). [{a,"a"}, {b,"b"}] ok 7> io:fwrite("~15lp~n", [S]). [{a,[97]}, {b,[98]}] ok
Unicode 轉換修飾符
t
指定如何處理 atom、字串和二進位資料中拉丁-1 字碼點範圍之外的字元。例如,印出包含大於 255 字元的 atom8> io:fwrite("~p~n",[list_to_atom([1024])]). '\x{400}' ok 9> io:fwrite("~tp~n",[list_to_atom([1024])]). 'Ѐ' ok
預設情況下,Erlang 僅偵測拉丁-1 範圍內的字元列表作為字串,但可以使用
+pc unicode
標誌來變更此行為(詳細資訊請參閱printable_range/0
)。例如10> io:fwrite("~p~n",[[214]]). "Ö" ok 11> io:fwrite("~p~n",[[1024]]). [1024] ok 12> io:fwrite("~tp~n",[[1024]]). [1024] ok
但如果 Erlang 使用
+pc unicode
啟動13> io:fwrite("~p~n",[[1024]]). [1024] ok 14> io:fwrite("~tp~n",[[1024]]). "Ѐ" ok
類似地,如果指定了
t
修飾符,看起來像 UTF-8 編碼字串的二進位資料會以二進位字串語法輸出15> io:fwrite("~p~n", [<<208,128>>]). <<208,128>> ok 16> io:fwrite("~tp~n", [<<208,128>>]). <<"Ѐ"/utf8>> ok 17> io:fwrite("~tp~n", [<<128,128>>]). <<128,128>> ok
W
- 以與~w
相同的方式寫入資料,但會額外取得一個參數,該參數是詞彙列印的最大深度。此深度以下的任何內容都會替換為...
。例如,使用上面的T
8> io:fwrite("~W~n", [T,9]). [{attributes,[[{id,age,1.5},{mode,explicit},{typename,...}], [{id,cho},{mode,...},{...}]]},{typename,'Person'}, {tag,{'PRIVATE',3}},{mode,implicit}] ok
如果達到最大深度,則無法在結果輸出中讀取。此外,tuple 中的
,...
形式表示 tuple 中有更多元素,但這些元素低於列印深度。P
- 以與~p
相同的方式寫入資料,但會額外取得一個參數,該參數是詞彙列印的最大深度。此深度以下的任何內容都會替換為...
,例如9> io:fwrite("~62P~n", [T,9]). [{attributes,[[{id,age,1.5},{mode,explicit},{typename,...}], [{id,cho},{mode,...},{...}]]}, {typename,'Person'}, {tag,{'PRIVATE',3}}, {mode,implicit}] ok
B
- 以 2-36 進位印出整數,預設進位為 10。負整數會印出前導破折號。精確度欄位選擇進位,例如
1> io:fwrite("~.16B~n", [31]). 1F ok 2> io:fwrite("~.2B~n", [-19]). -10011 ok 3> io:fwrite("~.36B~n", [5*36+35]). 5Z ok
X
- 類似於B
,但會額外取得一個參數,該參數是要插入數字之前的前綴,但要在前導破折號(如果有的話)之後。前綴可以是可能很深的字元列表或 atom。範例
1> io:fwrite("~X~n", [31,"10#"]). 10#31 ok 2> io:fwrite("~.16X~n", [-31,"0x"]). -0x1F ok
#
- 類似於B
,但會以 Erlang 樣式#
分隔的進位前綴印出數字。範例1> io:fwrite("~.10#~n", [31]). 10#31 ok 2> io:fwrite("~.16#~n", [-31]). -16#1F ok
b
- 類似於B
,但會印出小寫字母。x
- 類似於X
,但會印出小寫字母。+
- 類似於#
,但會印出小寫字母。n
- 寫入新行。i
- 忽略下一個詞彙。
此函數會傳回
ok
- 格式化成功。
如果發生錯誤,則沒有輸出。範例
1> io:fwrite("~s ~w ~i ~w ~c ~n",['abc def', 'abc def', {foo, 1},{foo, 1}, 65]).
abc def 'abc def' {foo,1} A
ok
2> io:fwrite("~s", [65]).
** exception error: bad argument
in function io:format/3
called as io:format(<0.53.0>,"~s","A")
在此範例中,嘗試使用字串格式化指令 "~s"
輸出單一字元 65。
-spec get_chars(Prompt, Count) -> Data | server_no_data() when Prompt :: prompt(), Count :: non_neg_integer(), Data :: string() | unicode:unicode_binary().
-spec get_chars(IoDevice, Prompt, Count) -> Data | server_no_data() when IoDevice :: device(), Prompt :: prompt(), Count :: non_neg_integer(), Data :: string() | unicode:unicode_binary().
從 IoDevice
讀取 Count
個字元,並以 Prompt
提示。
此函數會傳回
Data
- 輸入字元。如果 I/O 裝置支援 Unicode,則資料可以表示大於 255 的字碼點(latin1
範圍)。如果 I/O 伺服器設定為傳遞二進位資料,則會以 UTF-8 編碼(無論 I/O 裝置是否支援 Unicode)。如果您希望資料以 latin1 編碼的二進位資料傳回,則應改用file:read/2
。eof
- 遇到檔案結尾。{error, ErrorDescription}
- 其他(罕見)錯誤情況,例如如果從 NFS 檔案系統讀取,則為{error, estale}
。
-spec get_line(Prompt) -> Data | server_no_data() when Prompt :: prompt(), Data :: string() | unicode:unicode_binary().
-spec get_line(IoDevice, Prompt) -> Data | server_no_data() when IoDevice :: device(), Prompt :: prompt(), Data :: string() | unicode:unicode_binary().
從 IoDevice
讀取一行,並以 Prompt
提示。
此函數會傳回
Data
- 以換行符號(或檔案結尾)終止的行中的字元。如果 I/O 裝置支援 Unicode,則資料可以表示大於 255 的字碼點(latin1
範圍)。如果 I/O 伺服器設定為傳遞二進位資料,則會以 UTF-8 編碼(無論 I/O 裝置是否支援 Unicode)。如果您希望資料以 latin1 編碼的二進位資料傳回,則應改用file:read_line/1
。eof
- 遇到檔案結尾。{error, ErrorDescription}
- 其他(罕見)錯誤情況,例如如果從 NFS 檔案系統讀取,則為{error, estale}
。
等同於 getopts(standard_io)
。
-spec getopts(IoDevice) -> [getopt()] | {error, Reason} when IoDevice :: device(), Reason :: term().
請求 IoDevice
的所有可用選項及其目前值。
例如
1> {ok,F} = file:open("/dev/null",[read]).
{ok,<0.42.0>}
2> io:getopts(F).
[{binary,false},{encoding,latin1}]
在這裡,檔案 I/O 伺服器會傳回檔案的所有可用選項,這些選項是預期的選項:encoding
和 binary
。但是,標準 shell 有更多選項
3> io:getopts().
[{expand_fun,#Fun<group.0.120017273>},
{echo,true},
{binary,false},
{encoding,unicode},
{terminal,true},
{stdout,true},
{stderr,true},
{stdin,true}]
正如所見,此範例是在終端機支援 Unicode 輸入和輸出的環境中執行。
stdin
、stdout
和 stderr
選項是唯讀的,表示串流是否為終端機。當它是終端機時,Erlang 在其上執行的大多數系統都允許使用 ANSI 跳脫碼來控制終端機的輸入或輸出。
terminal
是 stdout
的別名。
有關其他選項的說明,請參閱 setopts/1
。
-spec nl() -> ok.
等同於 nl(standard_io)
。
-spec nl(IoDevice) -> ok when IoDevice :: device().
將新行寫入標準輸出 (IoDevice
)。
-spec parse_erl_exprs(IoDevice, Prompt, StartLocation) -> Result when IoDevice :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Result :: parse_ret().
-spec parse_erl_exprs(IoDevice, Prompt, StartLocation, Options) -> Result when IoDevice :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Options :: erl_scan:options(), Result :: parse_ret().
從 IoDevice
讀取數據,並以 Prompt
提示。
從位置 StartLocation
開始讀取。引數 Options
會作為函式 erl_scan:tokens/4
的引數 Options
傳遞。資料會被 Token 化並剖析,就像它是一系列的 Erlang 運算式,直到到達最終的點 (.
)。
此函數會傳回
{ok, ExprList, EndLocation}
- 剖析成功。{eof, EndLocation}
- Token 化工具遇到檔案結尾。eof
- I/O 伺服器遇到檔案結尾。{error, ErrorInfo, ErrorLocation}
- 在 Token 化或剖析時發生錯誤。{error, ErrorDescription}
- 其他(罕見)錯誤情況,例如如果從 NFS 檔案系統讀取,則為{error, estale}
。
範例
25> io:parse_erl_exprs('enter>').
enter>abc(), "hey".
{ok, [{call,1,{atom,1,abc},[]},{string,1,"hey"}],2}
26> io:parse_erl_exprs('enter>').
enter>abc("hey".
{error,{1,erl_parse,["syntax error before: ",["'.'"]]},2}
-spec parse_erl_form(Prompt) -> Result when Prompt :: prompt(), Result :: parse_form_ret().
-spec parse_erl_form(IoDevice, Prompt) -> Result when IoDevice :: device(), Prompt :: prompt(), Result :: parse_form_ret().
-spec parse_erl_form(IoDevice, Prompt, StartLocation) -> Result when IoDevice :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Result :: parse_form_ret().
-spec parse_erl_form(IoDevice, Prompt, StartLocation, Options) -> Result when IoDevice :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Options :: erl_scan:options(), Result :: parse_form_ret().
從 IoDevice
讀取數據,並以 Prompt
提示。
從位置 StartLocation
開始讀取。引數 Options
會作為函式 erl_scan:tokens/4
的引數 Options
傳遞。資料會被 Token 化並剖析,就像它是 Erlang 表單(Erlang 原始檔中的有效 Erlang 運算式之一),直到到達最終的點 (.
)。
此函數會傳回
{ok, AbsForm, EndLocation}
- 剖析成功。{eof, EndLocation}
- Token 化工具遇到檔案結尾。eof
- I/O 伺服器遇到檔案結尾。{error, ErrorInfo, ErrorLocation}
- 在 Token 化或剖析時發生錯誤。{error, ErrorDescription}
- 其他(罕見)錯誤情況,例如如果從 NFS 檔案系統讀取,則為{error, estale}
。
-spec printable_range() -> unicode | latin1.
傳回使用者要求的可列印 Unicode 字元範圍。
使用者可以請求一系列字元,這些字元在 shell 和格式化函式的字串啟發式偵測中被視為可列印。這是透過在啟動 Erlang 時提供 +pc <range>
來完成的。
<range>
的唯一有效值為 latin1
和 unicode
。latin1
表示只有字碼點 < 256(控制字元等等除外)被視為可列印。unicode
表示所有 Unicode 字元範圍中的所有可列印字元都被 I/O 函式視為可列印。
預設情況下,Erlang 在啟動時,只有 latin1
範圍的字元才表示整數列表是字串。
使用此設定的最簡單方法是呼叫 io_lib:printable_list/1
,它會使用此函式的傳回值來判斷列表是否為可列印字元的字串。
注意
在未來的版本中,此函式可能會傳回更多值和範圍。為避免相容性問題,建議使用函式
io_lib:printable_list/1
。
-spec put_chars(CharData) -> ok when CharData :: unicode:chardata().
-spec put_chars(IoDevice, CharData) -> ok when IoDevice :: device(), CharData :: unicode:chardata().
將 CharData
的字元寫入 IoDevice
。
如果您想要將 latin1 編碼的位元組寫入 IoDevice
,則應改用 file:write/2
。
-spec read(Prompt) -> Result when Prompt :: prompt(), Result :: {ok, Term :: term()} | server_no_data() | {error, ErrorInfo}, ErrorInfo :: erl_scan:error_info() | erl_parse:error_info().
-spec read(IoDevice, Prompt) -> Result when IoDevice :: device(), Prompt :: prompt(), Result :: {ok, Term :: term()} | server_no_data() | {error, ErrorInfo}, ErrorInfo :: erl_scan:error_info() | erl_parse:error_info().
從標準輸入 (IoDevice
) 讀取一個詞條 Term
,並以 Prompt
提示。
此函數會傳回
{ok, Term}
- 剖析成功。eof
- 遇到檔案結尾。{error, ErrorInfo}
- 剖析失敗。{error, ErrorDescription}
- 其他(罕見)錯誤情況,例如如果從 NFS 檔案系統讀取,則為{error, estale}
。
-spec read(IoDevice, Prompt, StartLocation) -> Result when IoDevice :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Result :: {ok, Term :: term(), EndLocation :: erl_anno:location()} | {eof, EndLocation :: erl_anno:location()} | server_no_data() | {error, ErrorInfo, ErrorLocation :: erl_anno:location()}, ErrorInfo :: erl_scan:error_info() | erl_parse:error_info().
-spec read(IoDevice, Prompt, StartLocation, Options) -> Result when IoDevice :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Options :: erl_scan:options(), Result :: {ok, Term :: term(), EndLocation :: erl_anno:location()} | {eof, EndLocation :: erl_anno:location()} | server_no_data() | {error, ErrorInfo, ErrorLocation :: erl_anno:location()}, ErrorInfo :: erl_scan:error_info() | erl_parse:error_info().
從 IoDevice
讀取一個詞條 Term
,並以 Prompt
提示。
讀取從位置 StartLocation
開始。參數 Options
會作為函式 erl_scan:tokens/4
的參數 Options
傳遞。
此函數會傳回
{ok, Term, EndLocation}
- 解析成功。{eof, EndLocation}
- 遇到檔案結尾。{error, ErrorInfo, ErrorLocation}
- 解析失敗。{error, ErrorDescription}
- 其他(罕見)錯誤情況,例如如果從 NFS 檔案系統讀取,則為{error, estale}
。
-spec rows() -> {ok, pos_integer()} | {error, enotsup}.
等同於 rows(standard_io)
。
-spec rows(IoDevice) -> {ok, pos_integer()} | {error, enotsup} when IoDevice :: device().
擷取 IoDevice
的列數(即終端機的高度)。
此函式僅適用於終端裝置,對於所有其他 I/O 裝置,此函式會回傳 {error, enotsup}
。
-spec scan_erl_exprs(Prompt) -> Result when Prompt :: prompt(), Result :: erl_scan:tokens_result() | server_no_data().
-spec scan_erl_exprs(Device, Prompt) -> Result when Device :: device(), Prompt :: prompt(), Result :: erl_scan:tokens_result() | server_no_data().
-spec scan_erl_exprs(Device, Prompt, StartLocation) -> Result when Device :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Result :: erl_scan:tokens_result() | server_no_data().
-spec scan_erl_exprs(Device, Prompt, StartLocation, Options) -> Result when Device :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Options :: erl_scan:options(), Result :: erl_scan:tokens_result() | server_no_data().
從 IoDevice
讀取數據,並以 Prompt
提示。
讀取從位置 StartLocation
開始。參數 Options
會作為函式 erl_scan:tokens/4
的參數 Options
傳遞。資料會被標記化,就像它是一連串 Erlang 表達式,直到遇到最終的點號 (.
) 為止。此標記也會被回傳。
此函數會傳回
{ok, Tokens, EndLocation}
- 標記化成功。{eof, EndLocation}
- Token 化工具遇到檔案結尾。eof
- I/O 伺服器遇到檔案結尾。{error, ErrorInfo, ErrorLocation}
- 標記化時發生錯誤。{error, ErrorDescription}
- 其他(罕見)錯誤情況,例如如果從 NFS 檔案系統讀取,則為{error, estale}
。
範例
23> io:scan_erl_exprs('enter>').
enter>abc(), "hey".
{ok,[{atom,1,abc},{'(',1},{')',1},{',',1},{string,1,"hey"},{dot,1}],2}
24> io:scan_erl_exprs('enter>').
enter>1.0er.
{error,{1,erl_scan,{illegal,float}},2}
-spec scan_erl_form(Prompt) -> Result when Prompt :: prompt(), Result :: erl_scan:tokens_result() | server_no_data().
-spec scan_erl_form(IoDevice, Prompt) -> Result when IoDevice :: device(), Prompt :: prompt(), Result :: erl_scan:tokens_result() | server_no_data().
-spec scan_erl_form(IoDevice, Prompt, StartLocation) -> Result when IoDevice :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Result :: erl_scan:tokens_result() | server_no_data().
-spec scan_erl_form(IoDevice, Prompt, StartLocation, Options) -> Result when IoDevice :: device(), Prompt :: prompt(), StartLocation :: erl_anno:location(), Options :: erl_scan:options(), Result :: erl_scan:tokens_result() | server_no_data().
從 IoDevice
讀取數據,並以 Prompt
提示。
從位置 StartLocation
(1
) 開始讀取。參數 Options
會作為函式 erl_scan:tokens/4
的參數 Options
傳遞。資料會被標記化,就像它是一個 Erlang 表單(Erlang 原始檔中有效的 Erlang 表達式之一),直到遇到最終的點號 (.
) 為止。最後這個標記也會被回傳。
回傳值與 scan_erl_exprs/4
的相同。
-spec setopts(IoDevice, Opts) -> ok | {error, Reason} when IoDevice :: device(), Opts :: [setopt()], Reason :: term().
設定 IoDevice
的選項。 可用的選項和值因 I/O 裝置而異。
如需特定 I/O 裝置上支援的選項及其目前值的列表,請使用函式 getopts/1
。
OTP I/O 裝置支援的選項和值如下:
binary
、list
或{binary, boolean()}
- 如果設定為二進位模式 (binary
或{binary, true}
),I/O 伺服器會將二進位資料(以 UTF-8 編碼)作為對get_line
、get_chars
以及(如果可能)get_until
請求的回應(詳細資訊請參閱《使用者指南》中的「Erlang I/O 協定」章節)。直接的影響是,get_chars/2,3
和get_line/1,2
會針對受影響的 I/O 裝置回傳 UTF-8 二進位資料,而不是字元列表。預設情況下,OTP 中的所有 I/O 裝置都設定為
list
模式。但是,I/O 函式可以處理任何這些模式,因此其他使用者撰寫的、作為 I/O 伺服器用戶端的模組也應該可以處理。此選項由
standard_io/0
、user/0
和file:io_server/0
I/O 伺服器支援。{echo, boolean()}
- 表示終端機是否要回顯輸入。僅支援標準 shell I/O 伺服器 (group.erl
){expand_fun, expand_fun()}
- 提供一個函式用於像 Erlang shell 一樣進行 Tab 鍵補全(擴展)。當使用者按下 *Tab* 鍵時會呼叫此函式。當呼叫讀取行函式(例如get_line/1,2
)時,擴展會處於啟用狀態。此函式會以反向字串的形式,將目前行(直到游標處)作為參數呼叫。它會回傳一個三元組:
{yes|no, string(), list()}
。如果第一個元素是no
,則會發出嗶聲,否則擴展會靜默進行;第二個元素是一個字串,會在游標位置輸入;第三個元素是可能的擴展列表。如果此列表不為空,則會列印在目前的輸入行下方。可能擴展的列表可以用不同的方式格式化,以便讓更進階的擴展建議對使用者更具可讀性,請參閱edlin_expand:expand/2
的說明文件。簡單範例(除了空行外,在任何內容上發出嗶聲,空行會擴展為
"quit"
)fun("") -> {yes, "quit", []}; (_) -> {no, "", ["quit"]} end
此選項僅受標準 shell (
group.erl
) 支援。{log, none | output | input | all}
- 告知 I/O 伺服器它應該記錄 I/O 請求。請求將以info
層級記錄到[otp, kernel, io, input | output | ctrl]
網域,並附帶以下報告:#{ request := IoRequest, server := pid(), server_name => term() }.
請務必注意,應格外小心,確保這些記錄報告不會記錄到
standard_io/0
,因為這可能會導致系統進入無限迴圈。範例
1> logger:set_primary_config(level, info). ok 2> logger:add_handler(stdout, logger_std_h, #{ config => #{ file => "stdout.log" }}). ok 3> io:setopts(user, [{log, output}]). ok 4> io:format(user, "Hello~n", []). Hello ok 5> file:read_file("stdout.log"). {ok,<<"2024-11-14T09:53:49.275085+01:00 info: <0.89.0> wrote to user, Hello\n">>}
並非所有 I/O 伺服器都支援此選項。使用
io:getopts/1
檢查它是否可用。注意
Erlang/OTP 中的 I/O 伺服器會將 記錄器網域設定為
[otp, kernel, io, input | output]
。預設的logger
處理常式不會列印此網域,因此您需要啟用它。這可以透過新增類似這樣的篩選器來完成:logger:add_handler_filter(default, io_domain, {fun logger_filters:domain/2, {log,sub,[otp,kernel,io]}}).
{encoding, latin1 | unicode}
- 指定如何從 I/O 裝置輸入或輸出字元,這表示,例如,終端機設定為處理 Unicode 輸入和輸出,或者檔案設定為處理 UTF-8 資料編碼。此選項不會影響 I/O 函式回傳資料的方式,也不會影響資料在 I/O 協定中的傳送方式,它只會影響 I/O 裝置如何處理到「實體」裝置的 Unicode 字元。
當系統啟動時,標準 shell 會設定為
unicode
或latin1
編碼。編碼是透過 Unix 類系統上的LANG
或LC_CTYPE
環境變數或在其他系統上透過其他方式設定的。因此,如果 I/O 裝置支援,使用者可以輸入 Unicode 字元,且 I/O 裝置會處於{encoding, unicode}
模式。如果執行階段系統的假設錯誤,可以透過設定此選項來變更模式。注意
在 OTP 26.0 之前,當 Erlang 以
-oldshell
或-noshell
旗標啟動時(例如,在escript
中),standard_io
的預設編碼設定為latin1
,這表示任何字元 > 碼位 255 都會被逸出,並且預期輸入是純 8 位元 ISO Latin-1。從 OTP 26.0 開始,如果standard_io
支援,則它始終預設為unicode
,否則預設為latin1
。如果您想要在
standard_io
上傳送原始位元組,現在您始終需要將編碼明確設定為latin1
;否則,碼位 128-255 將會轉換為 UTF-8。最好透過將核心設定參數 standard_io_encoding 設定為latin1
來完成此操作。檔案也可以設定為
{encoding, unicode}
,這表示資料會以 UTF-8 格式寫入和讀取。檔案可以使用更多編碼,請參閱下方。標準 shell (
group.erl
,包括 Windows 上的werl
)、「oldshell」(user.erl
) 和檔案 I/O 伺服器都支援{encoding, unicode | latin1}
。{encoding, utf8 | utf16 | utf32 | {utf16,big} | {utf16,little} | {utf32,big} | {utf32,little}}
- 對於磁碟檔案,編碼可以設定為各種 UTF 變體。這樣做的效果是,預期資料會以指定的編碼從檔案中讀取,並且資料會以指定的編碼寫入磁碟檔案。{encoding, utf8}
在檔案上的效果與{encoding, unicode}
相同。擴展編碼僅在磁碟檔案上支援(透過函式
file:open/2
開啟)。
-spec write(Term) -> ok when Term :: term().
將詞條 Term
寫入 IoDevice
。