Perl: styring af sti kodninger på Windows

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg kæmper med at arbejde med en sti, der indeholder ikke engelske tegn (Activestate Perl, Windows XP). Hvordan åbner, skriver, kopierer osv. En fil, der er placeret i en sti med lad sige græsk/russisk/fransk accent tegn? Lad os sige, at den mappe, jeg vil kopiere min text.txt fil til, er: C:Documents and SettingsσταDesktop


use File::Spec;
my $save = File::Spec->canonpath( $mw->chooseDirectory() );

my $file = catfile($save , "renamed\_text.txt");

my $input = "üüü	ext.txt";
copy ($input, $file) or die "File cannot be copied.";

Bedste reference


Jeg havde det samme problem i et projekt et par år tilbage (vores PAR-pakket GUI app måtte arbejde under Shift-JIS-kodning). Jeg forsøgte masser af teknikker til at gøre Perl 5.8 gøre det rigtigt automatisk. Til sidst var min kedelig-men-effektive løsning at kode for hvert filnavn lige før det blev sendt til bygningerne.


Først skal du oprette hjælpefunktionen:


use Encode;
use Win32::Codepage;
my $encoding = Win32::Codepage::get\_encoding() || q{};
if ($encoding) {
    $encoding = Encode::resolve\_alias($encoding) || q{};
}
sub encode\_filename {
    my ($filename) = @\_;
    return $encoding ? encode($encoding, $filename) : $filename;
}


Brug derefter det overalt :


next if (! -d encode\_filename($tmpldir));
my $file = SWF::File->new(encode\_filename($dest));
@entries = File::Slurp::read\_dir(encode\_filename($srcdir));
etc...


Jeg skrev endda en lille checker for at sikre, at jeg brugte det overalt!


egrep "-[a-zA-Z] |open[^\_]|[^ ]parse|unlink|symlink|mkdir[^\_]|mkpath|rename[^']|File::Copy::copy|rmtree|getTemplate[^D]|write\_file|read\_file|read\_dir" *.pl `find lib -name '*.pm'` | grep -
v encode\_filename | egrep -v '^[^:]+: *(#|\_announce|debug)'


Hvis du savner lige en, får du 'Wide-character' advarslen ved kørselstid ...

Andre referencer 1


Jeg har ikke privilegier til at stemme på svaret fra Chris Dolan, men jeg har løst dette problem for stinavn her i Japan med den samme løsning baseret på Win32 :: Codepage. [11]


Dette har sandsynligvis brug for bekræftelse, men jeg tror, ​​at Perl antager UTF8 for alle ikke-ASCII-navne. På Linux og OS X fungerer det fint, fordi OS-stienavnene er kodet i UTF8. Men på ældre versioner af Windows (før Windows 7?) Er vejnavne kodet i landets landestandard (fx Shift-jis her i Japan). Så, alle Perl kalder op, at returneringsnavne med ikke-ASCII-tegn bliver ødelagt.


Den løsning, jeg brugte, var at finde den lokale kodning ved hjælp af Win32: Codepage og derefter kode det til UTF8, når du læser filer. Derefter ville jeg, når jeg skrev (eller opdaterer) filer, dekode tilbage til lokalekodningen.

Andre referencer 2


Perls oprindelige funktioner kan ikke bruges i dette tilfælde. Brug funktioner i Win32 modul, der understøtter Unicode-tegn. Win32 blev først udgivet med perl v5.8.7. [12] [13]

Andre referencer 3


Jeg opdagede, at jeg måtte deaktivere UAC (User Access Control) på Microsoft Windows Vista, før jeg med held kunne installere enten Win32::Locale eller Win32::Codepage. (Tak, Chris Dolan, for at skrive sidstnævnte modul.) [14]

Andre referencer 4


Jeg havde også problemer med UAC (User Access Control) på Windows 7 og nyere.
Jeg fandt endelig ud af, at adgang til den nødvendige registreringsdatabasenøgle kun har læsetilladelser siden WIndows Vista.
Du kan nemt patch Win32 :: Codepage til at arbejde uden administrative rettigheder, hvis du åbner filen i dit yndlingsredaktør og erstatter:


  $codekey = Win32::TieRegistry->new($CODEPAGE\_REGISTRY\_KEY,
                                     { Delimiter => "/" }
                                    );

  $codekey = Win32::TieRegistry->new($CODEPAGE\_REGISTRY\_KEY,
                                     { Access=>"KEY\_READ", Delimiter => "/" }
                                    );


Dette har hjulpet min installation.