2015-07-12 7 views
5

Sto cercando alcune linee guida su come creare nomi di file con caratteri Unicode. Si consideri:Creazione di nomi file con caratteri Unicode

use open qw(:std :utf8); 
use strict; 
use utf8; 
use warnings; 

use Data::Dump; 
use Encode qw(encode); 

my $utf8_file_name1 = encode('UTF-8', 'æ1', Encode::FB_CROAK | Encode::LEAVE_SRC); 
my $utf8_file_name2 = 'æ2'; 
dd $utf8_file_name1; 
dd $utf8_file_name2; 
qx{touch $utf8_file_name1}; 
qx{touch $utf8_file_name2}; 
print (qx{ls æ*}); 

L'output è:

"\xC3\xA61" 
"\xE62" 
æ1 
æ2 

Perché non importa se ho codificare il nome del file in UTF8 o no? (Il nome file diventa comunque UTF8 valido in entrambi i casi.)

risposta

5

A causa di un bug chiamato "The Unicode Bug". L'equivalente del seguente sta accadendo:

use Encode qw(encode_utf8 is_utf8); 

my $bytes = is_utf8($str) ? encode_utf8($str) : $str; 

is_utf8 verifiche che del formato di archiviazione due stringa viene utilizzato da scalare. Questo è un dettaglio di implementazione interno di cui non dovresti mai preoccuparti, ad eccezione di The Unicode Bug.

tuo programma funziona perché encode restituisce sempre una stringa per la quale is_utf8 restituisce false, e use utf8; restituisce sempre una stringa per la quale is_utf8 restituisce vero se la stringa contiene caratteri non ASCII.

Se non si è encode come si dovrebbe, a volte si ottiene il risultato sbagliato. Ad esempio, se si fosse utilizzato "\x{E6}2" anziché 'æ2', si otterrebbe un nome file diverso anche se le stringhe hanno la stessa lunghezza e gli stessi caratteri.

$ dir 
total 0 

$ perl -wE' 
    use utf8; 
    $fu="æ"; 
    $fd="\x{E6}"; 
    say sprintf "%vX", $_ for $fu, $fd; 
    say $fu eq $fd ? "eq" : "ne"; 
    system("touch", $_) for "u".$fu, "d".$fd 
' 
E6 
E6 
eq 

$ dir 
total 0 
-rw------- 1 ikegami ikegami 0 Jul 12 12:18 uæ 
-rw------- 1 ikegami ikegami 0 Jul 12 12:18 d? 
+0

Interessante, hai un riferimento a questo bug? Sarà risolto? –

+0

Dubito che ci sia un biglietto. Risolvendolo probabilmente si romperà più codice di quello che verrà risolto. – ikegami

+0

Ho qualche difficoltà a capire come funziona questo bug .., ma come capisco ora, la conclusione è che dovrei sempre codificare i nomi dei file usando per esempio 'Encode :: encode' (come ho fatto con' $ utf8_filename1') prima di creare il file? –