open - Perl pragma 用於設定輸入和輸出的 PerlIO 預設層
use open IN => ':crlf', OUT => ':raw';
open my $in, '<', 'foo.txt' or die "open failed: $!";
my $line = <$in>; # CRLF translated
close $in;
open my $out, '>', 'bar.txt' or die "open failed: $!";
print $out $line; # no translation of bytes
close $out;
use open OUT => ':encoding(UTF-8)';
use open IN => ':encoding(iso-8859-7)';
use open IO => ':locale';
# IO implicit only for :utf8, :encoding, :locale
use open ':encoding(UTF-8)';
use open ':encoding(iso-8859-7)';
use open ':locale';
# with :std, also affect global standard handles
use open ':std', ':encoding(UTF-8)';
use open ':std', OUT => ':encoding(cp1252)';
use open ':std', IO => ':raw :encoding(UTF-16LE)';
現在已實作完整的 I/O 層支援,前提是 Perl 已設定為使用 PerlIO 作為其 IO 系統(自 5.8 以來一直是預設值,且自 5.16 以來是唯一支援的設定)。
open
pragma 是宣告所有 I/O 的預設「層」(以前稱為「規範」)的其中一個介面。此 pragma 的詞彙範圍內找到的任何 open()、readpipe()(又稱 qx//)和類似運算子,都將透過 ${^OPEN}
變數使用宣告的預設值。
依慣例,層會以冒號開頭。你可以指定多個層的堆疊,作為空格分隔的字串。有關可用層的更多資訊,請參閱 PerlIO。
使用 IN
子 pragma,你可以宣告輸入串流的預設層,使用 OUT
子 pragma,你可以宣告輸出串流的預設層。使用 IO
子 pragma(對於 :utf8
、:locale
或 :encoding
可以省略),你可以同時控制輸入和輸出串流。
當 open() 給予一個明確的層清單(使用三個參數語法)時,它們會覆寫使用此語用程式宣告的清單。open() 也可以給予一個單一冒號 (:) 作為層名稱,以覆寫此語用程式並使用 PerlIO 中「預設值和如何覆寫它們」中詳述的預設值。
若要從任意文字編碼轉換並轉換為任意文字編碼,請使用 :encoding
層。:encoding
中編碼名稱的比對並不嚴格:大小寫不重要,而且許多編碼有數個別名。有關詳細資料和支援的區域清單,請參閱 Encode::Supported。
如果您想根據您的區域環境變數設定編碼層,您可以使用 :locale
偽層。例如
$ENV{LANG} = 'ru_RU.KOI8-R';
# the :locale will probe the locale environment variables like LANG
use open OUT => ':locale';
open(my $out, '>', 'koi8') or die "open failed: $!";
print $out chr(0x430); # CYRILLIC SMALL LETTER A = KOI8-R 0xc1
close $out;
open(my $in, '<', 'koi8') or die "open failed: $!";
printf "%#x\n", ord(<$in>); # this should print 0xc1
close $in;
:locale
的邏輯在「編碼」中的「:locale
子語用程式」中完整說明,但簡而言之,它首先嘗試 nl_langinfo(CODESET),然後從 LC_ALL 和 LANG 區域環境變數中猜測。:locale
也會隱含開啟 :std
。
:std
不是一個層,而是一個額外的子語用程式。當在匯入清單中指定時,它會啟動一個額外的功能,將選取的輸入/輸出控制項層推送到標準檔案控制項(STDIN、STDOUT、STDERR)。如果新的層和現有的層堆疊都以 :encoding
層結尾,現有的 :encoding
層也會被移除。
例如,如果輸入和輸出都被選為 :encoding(UTF-8)
,:std
會表示 STDIN、STDOUT 和 STDERR 也會設定為 :encoding(UTF-8)
。另一方面,如果只有輸出被選為 :encoding(koi8r)
,:std
會導致只有 STDOUT 和 STDERR 會在 koi8r
中。
:std
的效果並非字面上的,因為它會修改全域控制項的層堆疊。如果您只想套用此全域效果,而不是套用在該範圍內開啟的控制項的效果,您可以在其自己的字面範圍內孤立呼叫此語用程式。
{ use open ':std', IO => ':encoding(UTF-8)' }
在 Perl 5.34 之前,:std
只會套用第一個層,前提是它是 :utf8
或有層參數,例如 :encoding(UTF-8)
。自 Perl 5.34 起,它會套用它提供給 ${^OPEN}
的相同層堆疊。
PerlIO::Layer
中有一個類別方法 find
,它以 XS 程式碼實作。它是由 import
呼叫來驗證層級
PerlIO::Layer::->find("perlio")
回傳值(如果已定義)是一個 Perl 物件,其類別為 PerlIO::Layer
,它是由 perlio.c 中的 C 程式碼建立的。目前在 Perl 層級中,你還無法對物件執行任何有用的操作。
perlfunc 中的「binmode」、perlfunc 中的「open」、perlunicode、PerlIO、encoding