內容

名稱

PerlIO::via - Perl 中實作 PerlIO 層的輔助類別

語法

use PerlIO::via::Layer;
open($fh,"<:via(Layer)",...);

use Some::Other::Package;
open($fh,">:via(Some::Other::Package)",...);

說明

PerlIO::via 模組讓您可以在 Perl 中開發 PerlIO 層,而不需要深入了解使用 XS 作為 Perl 介面的 C 編程。

一個範例模組 PerlIO::via::QuotedPrint 包含在 Perl 5.8.0 中,還有更多範例模組可以在 CPAN 取得,例如 PerlIO::via::StripHTMLPerlIO::via::Base64。例如,PerlIO::via::StripHTML 模組讓您可以說

	use PerlIO::via::StripHTML;
	open( my $fh, "<:via(StripHTML)", "index.html" );
        my @line = <$fh>;

以陣列取得 HTML 檔案的文字,並自動移除所有 HTML 標籤。

請注意,如果層是在 PerlIO::via:: 名稱空間中建立的,則不需要完全限定。如果指定的模組名稱不存在為完全限定的模組名稱,PerlIO::via 模組會加上 PerlIO::via:: 名稱空間的前綴。

預期的的方法

若要建立在 Perl 中實作 PerlIO 層的 Perl 模組(相對於在 C 中使用 XS 作為 Perl 介面),您需要提供下列子常式。建議在 PerlIO::via:: 名稱空間中建立這些 Perl 模組,以便它們可以輕鬆地在 CPAN 上找到,並使用 PerlIO::via 模組本身的預設名稱空間功能。

請注意,這是 Perl 最近開發的領域,因此這裡所描述的介面仍可能變更(希望會有更好的文件和更多範例)。

在以下方法說明中,$fh 將會參考一個 glob,它可以視為 Perl 檔案句柄。它指的是下層。如果該層位於堆疊的底部,則不會傳遞 $fh,基於這個原因以及為了維持與 TIEHANDLE 類別的某種程度的「相容性」,因此它會在最後傳遞。

$class->PUSHED([$mode,[$fh]])

應該傳回物件或類別,或在失敗時傳回 -1。(比較 TIEHANDLE。)參數是一個選用的模式字串(「r」、「w」、「w+」...)和 PerlIO 下層的檔案句柄。這是強制性的。

當該層作為 open 呼叫的一部分被推入時,PUSHED 會在實際開啟發生之前被呼叫,無論是透過 OPENSYSOPENFDOPEN 或讓下層進行開啟。

$obj->POPPED([$fh])

選用的 - 在該層即將被移除時呼叫。

$obj->UTF8($belowFlag,[$fh])

選用的 - 如果存在,它會在 PUSHED 傳回後立即被呼叫。如果該層預期資料會以 UTF-8 編碼,它應該傳回一個 true 值。如果它傳回 true,結果就像呼叫者已執行

":via(YourClass):utf8"

如果不存在或如果它傳回 false,則串流會保持 UTF-8 旗標清除。如果有一個下層,而且該層預期 UTF-8,則 $belowFlag 參數會為 true。

$obj->OPEN($path,$mode,[$fh])

選用的 - 如果不存在,則下層會進行開啟。如果存在,則在該層被推入後,對於正常的開啟進行呼叫。此函式可能會變更,因為沒有簡單的方法可以讓下層進行開啟,然後重新取得控制權。

$obj->BINMODE([$fh])

選用的 - 如果不存在,則該層會在 binmode($fh) 或推入 :raw 時被彈出。如果存在,則它應該在成功時傳回 0,在錯誤時傳回 -1,或傳回 undef 以彈出該層。

$obj->FDOPEN($fd,[$fh])

選用的 - 如果不存在,則下層會進行開啟。如果存在,則在該層被推入後,對於傳遞數字檔案描述子的開啟進行呼叫。此函式可能會變更,因為沒有簡單的方法可以讓下層進行開啟,然後重新取得控制權。

$obj->SYSOPEN($path,$imode,$perm,[$fh])

選擇性 - 如果不存在,則較低層會執行開啟。如果存在,則在層被推入後,針對傳遞數字模式和權限的 sysopen 類型開啟進行呼叫。此函式可能會變更,因為沒有簡單的方法可以讓較低層執行開啟,然後重新取得控制權。

$obj->FILENO($fh)

傳回類 Unix 檔案描述符的數字值。如果沒有,則傳回 -1。選擇性。預設值為 fileno($fh)。

$obj->READ($buffer,$len,$fh)

傳回置於 $buffer 中的八位元組數目(必須小於或等於 $len)。選擇性。預設值是改用 FILL。

$obj->WRITE($buffer,$fh)

傳回已成功寫入的 $buffer 中的八位元組數目。

$obj->FILL($fh)

應傳回要置於緩衝區中的字串。選擇性。如果未提供,則必須提供 READ 或拒絕在 PUSHED 中開啟用於讀取的控制代碼。

$obj->CLOSE($fh)

如果成功,應傳回 0,如果發生錯誤,應傳回 -1。選擇性。

$obj->SEEK($posn,$whence,$fh)

如果成功,應傳回 0,如果發生錯誤,應傳回 -1。選擇性。預設值是失敗,但這可能會在未來變更。

$obj->TELL($fh)

傳回檔案位置。選擇性。預設值待定。

$obj->UNREAD($buffer,$fh)

傳回已成功儲存的 $buffer 中的八位元組數目,以便在未來的 FILL/READ 呼叫中傳回。選擇性。預設值是將資料推入位於此資料上方的暫時層中。

$obj->FLUSH($fh)

清除任何緩衝寫入資料。也可能在可讀取控制代碼上呼叫。如果成功,應傳回 0,如果發生錯誤,應傳回 -1。

$obj->SETLINEBUF($fh)

選用。無回傳值。

$obj->CLEARERR($fh)

選用。無回傳值。

$obj->ERROR($fh)

選用。回傳錯誤狀態。預設為無錯誤,直到找出信號錯誤(die?)的機制。

$obj->EOF($fh)

選用。回傳檔案結尾狀態。預設為 FILL 或 READ 回傳值的函數。

範例

在 CPAN 上查看 PerlIO::via:: 名稱空間,以取得以 Perl 執行的 PerlIO 層範例。為了讓您了解 PerlIO 層執行的簡單程度,此處提供一個簡單範例。

範例 - 十六進位處理

提供下列模組,PerlIO::via::Hex

package PerlIO::via::Hex;

sub PUSHED
{
 my ($class,$mode,$fh) = @_;
 # When writing we buffer the data
 my $buf = '';
 return bless \$buf,$class;
}

sub FILL
{
 my ($obj,$fh) = @_;
 my $line = <$fh>;
 return (defined $line) ? pack("H*", $line) : undef;
}

sub WRITE
{
 my ($obj,$buf,$fh) = @_;
 $$obj .= unpack("H*", $buf);
 return length($buf);
}

sub FLUSH
{
 my ($obj,$fh) = @_;
 print $fh $$obj or return -1;
 $$obj = '';
 return 0;
}

1;

下列程式碼開啟輸出處理,將任何輸出轉換為輸出位元的十六進位轉儲:例如「A」將轉換為「41」(在基於 ASCII 的機器上,在 EBCDIC 平台上「A」將變成「c1」)

use PerlIO::via::Hex;
open(my $fh, ">:via(Hex)", "foo.hex");

而下列程式碼將讀取十六進位轉儲,並動態將其轉換回位元組

open(my $fh, "<:via(Hex)", "foo.hex");