2016-05-02 11 views
6

Oto prosty skrypt Perla, który ma napisać kodowanie UTF-8 pliku:W jakim kodowaniu readpipe zwraca wynik wykonanego polecenia?

use warnings; 
use strict; 

open (my $out, '>:encoding(utf-8)', 'tree.out') or die; 

print $out readpipe ('tree ~'); 

close $out; 

oczekiwać ja readpipe zwrócić kodowanie UTF-8 znaków od LANG jest ustawiony na en_US.UTF-8. Jednak patrząc na tree.out (upewniając się, że edytor rozpoznaje go jako zakodowany w UTF-8) pokazuje mi cały zniekształcony tekst.

Jeśli zmienię >:encoding(utf-8) w otwartym rachunku do >:encoding(latin-1) skrypt tworzy UTF-8 plik z oczekiwaną tekstu.

Wszystko to jest dla mnie trochę dziwne. Jakie jest wytłumaczenie tego zachowania?

+0

Zobacz [Enocde :: Ustawienia regionalne] (https://metacpan.org/pod/Encode::Locale), aby dowiedzieć się, jak włączyć informacje o lokalizacji. Dla bieżącego problemu: 'readpipe' zwraca bajty (które będą już zakodowane jako UTF-8). Warstwa PerlIO '>: encoding (utf-8)' zakoduje ją jeszcze raz podczas drukowania do pliku. Rozwiązanie: Konwertuj ciąg bajtów na ciąg Perla przed wydrukowaniem do pliku. Na przykład, użyj 'Encode :: decode()' –

Odpowiedz

2

readpipe powraca do perla ciąg niezdekodowanych bajtów. Wiemy, że ten ciąg jest kodowany w UTF-8, ale nie powiedziałeś Perlowi.

Warstwa IO na uchwycie wyjściowym pobiera ten ciąg, przyjmując, że jest to kodowanie w standardzie Unicode i ponownie koduje je jako bajty UTF-8.

Powodem, że warstwa IO Latin-1 wydaje się funkcjonować poprawnie jest to, że zapisuje każdy niezakodowany bajt niezmieniony, ponieważ pierwsze 256 kodów kodowych unicode ładnie koresponduje z latin-1.

Właściwą rzeczą będzie decode ciąg bajtów zwrócony przez readpipe do ciągu kodu, przed przesłaniem go do warstwy IO. Oświadczenie use open ':utf8', o którym wspomniał Borodin, powinno być wykonalnym rozwiązaniem, ponieważ readpipe jest konkretnie wspomniane w open manual page.

+0

* "readpipe" zwraca perl ciąg bajtów "* Czy mógłbyś połączyć się z dokumentacją, która tak mówi? – Borodin

+0

@Borodin, chciałbym, niestety, mam problem ze znalezieniem jakichkolwiek dokumentów na ten temat, które odzwierciedlają to, że został zmodyfikowany dla świata pocztowych warstw IO. Zastanawiam się, czy argument wiersza poleceń 'C' może zmodyfikować jego zachowanie, ale nie sprawdziłem. – tjd

+1

@Borodin [perlunicode: "Kiedy Unicode się nie dzieje"] (http://perldoc.perl.org/perlunicode.html#When-Unicode-Does-Not-Happen) – ThisSuitIsBlackNot

Powiązane problemy