2014-10-03 68 views
6

我有一個文件句柄在其中包含cp1252字符的文件上打開。我想把這個打開的文件句柄放到一個需要原始utf8字節的庫中,它將通過網絡發送這些文件。Perl將文件句柄就地/從cp1252流式傳輸到utf-8?

天真的方式做到這一點是寫文件拿出來與正確的編碼第二個文件,並給第二個文件句柄到庫:

use Fcntl qw/SEEK_SET/; 

open my $fh_1252, "<:encoding(cp1252)", "1252.txt" || die $!; 

open my $fh_utf8, "+>:encoding(utf8)", "utf8.txt" || die $!; 

while (<$fh_1252>){ print $fh_utf8 $_ }; 

seek($fh_utf8, 0, SEEK_SET); 

# now give $fh_utf8 to the library for transmission 

這似乎像一堆額外的工作。有沒有一種方法可以流式傳輸?我知道我可以使用IO :: Scalar去除寫入磁盤的需要,但是我仍然必須將整個內容讀入內存。似乎有一種方法可以用流水線進行流式處理,但我現在沒有想辦法做到這一點。

+0

你說的是Perl庫或非perl的庫/ propgram?你能給你的操作系統命名(unix/windows)嗎? – AnFi 2014-10-03 18:26:43

+1

注意:'open ...,「1252.txt」|| die!!;'表示開放......,(「1252.txt」|| die $!);'(它永遠不會死亡)。你想要'打開...,「1252.txt」或者死掉$ !;' – ikegami 2014-10-03 19:44:20

回答

3

您可以編寫自己的轉換模塊PerlIO並與:via(MODULE)一起使用。您的模塊可以通過Text::Iconv傳遞數據以從一個字符集轉換爲另一個字符集。

這種方式在手冊PerlIO::via(3pm)中描述。簡而言之,您需要創建自己的模塊,例如PerlIO::via::Example - 也就是說,你讓PerlIO/via目錄,並把那裏Example.pm,具有以下內容:

package PerlIO::via::Example; 

use strict; 
use warnings; 

use Text::Iconv; 
my $converter = Text::Iconv->new("windows-1252", "utf-8"); 

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) ? 'converted: ' . $converter->convert($line) : undef; 
    # 'converted: ' is added here for debugging purposes 
} 

sub WRITE 
{ 
    my ($obj,$buf,$fh) = @_; 
    $$obj .= $buf; # we do nothing here 
    return length($buf); 
} 

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

1; 

,然後用它在open喜歡這裏:

use strict; 
use warnings; 

use PerlIO::via::Example; 

open(my $fh, "<:via(Example)", "input.txt"); 
while (<$fh>) { 
    print; 
} 
close $fh; 
+0

這看起來好像會起作用,但工作在這個問題上的工程師迴應道:「如果我們正在處理一個文件,他的答案會奏效在本地文件系統上(在他的例子中,'input.txt'),但是我們只是從mogilefs獲得一個已經打開的文件句柄,所以我們不能通過他概述的新的PerlIO模塊。「非常棒的答案,謝謝! – 2014-11-07 17:31:06

0

您可以使用外部程序來轉換輸入文件。詳情請參閱perldoc -f open

open(my $ft, '-|' "iconf -f CP1252 -t UTF-8 1252.txt") || die $!; 

P.S. perl庫有更簡單的解決方案。以上是最通用的恕我直言。

相關問題