2010-11-20 14 views
3

Ich habe Probleme mit einem Pfad zu arbeiten, der nicht englische Zeichen enthält (Activestate Perl, Windows XP). Wie öffne, schreibe, kopiere ich etc. eine Datei in einem Pfad mit zB griechischen/russischen/französischen Akzentbuchstaben? Lassen Sie uns sagen, dass das Verzeichnis Ich möchte meine text.txt Datei kopieren ist: C:\Documents and Settings\στα\DesktopPerl: Verwalten von Pfadkodierungen unter Windows

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

my $file = catfile($save , "renamed_text.txt"); 

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

Ihr Code-Snippet hat ein Problem: Sie wollen "\\ text.txt" nicht "\ text.txt". Dies ist jedoch wahrscheinlich nicht dein endgültiges Problem. – Leolo

Antwort

0

Perl nativen Funktionen in diesem Fall nicht verwendet werden kann. Verwenden Sie Funktionen in Win32 Modul, die Unicode-Zeichen unterstützen. Win32 wurde zuerst mit Perl v5.8.7 veröffentlicht.

+0

Vielen Dank für Ihren Rat.Ich habe das Skript in geändert, außer (Win32 :: CopyFile ($ input, $ ansi_path, 1)) { my $ err = $^E; if ($ err == ERROR_ALREADY_EXISTS) { warn "Verzeichnis existiert, kein Problem \ n"; } else { die Win32 :: FormatMessage ($^E); } } ABER ES FUNKTIONIERT NICHT FÜR GRIECHISCH !! IRGENDEINE IDEE? – Richard

+0

Es tut mir leid. Ich habe derzeit kein Windows-System zum Testen. Wenn ich testen kann, werde ich meine Antwort aktualisieren. –

+0

Alans Antwort ist auf dem richtigen Weg, aber ist falsch. Sie können Perls native Funktionen mit einer breiten Zeichencodierung verwenden, aber Sie müssen die Dateinamen in die Systemcodierung codieren, bevor Sie die Dateinamen an Perl übergeben. Siehe meine Antwort. –

2

Ich hatte das gleiche Problem in einem Projekt vor ein paar Jahren zurück (unsere PAR-gepackte GUI-App musste unter Shift-JIS-Codierung arbeiten). Ich habe viele Techniken ausprobiert, um Perl 5.8 das automatisch richtig machen zu lassen. Am Ende war meine langwierige, aber effektive Lösung, JEDEN Dateinamen zu verschlüsseln, bevor er an die eingebauten Dateien übergeben wurde.

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; 
} 

Dann verwenden Sie es überall:

Zuerst die Nutzenfunktion einrichten

next if (! -d encode_filename($tmpldir)); 
my $file = SWF::File->new(encode_filename($dest)); 
@entries = File::Slurp::read_dir(encode_filename($srcdir)); 
etc... 

ich sogar ein wenig checker, um sicherzustellen, schrieb habe ich es überall!

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)' 

Wenn Sie auch nur eine verpassen, werden Sie die „Wide-Zeichen“ zur Laufzeit Warnung erhalten ...

2

Ich habe keine Privilegien, die Antwort von Chris Dolan stimmen, aber ich habe löste dieses Problem für Pfadnamen hier in Japan mit der gleichen Lösung basierend auf Win32::Codepage.

Dies muss wahrscheinlich bestätigt werden, aber ich denke, Perl übernimmt UTF8 für alle Nicht-ASCII-Pfadnamen. Unter Linux und OS X funktioniert das gut, weil die Pfadnamen des Betriebssystems in UTF8 codiert sind. Aber, auf älteren Versionen von Windows (vor Windows 7?) Sind Pfadnamen im Gebietsschema des Landes kodiert (z.B. Shift-jis hier in Japan). Daher werden alle Perl-Aufrufe, die Pfadnamen mit Nicht-ASCII-Zeichen zurückgeben, durcheinander gebracht.

Die Lösung, die ich verwendete, war, die Locale-Codierung mit Win32: Codepage zu finden und dann beim Lesen von Dateien in UTF8 zu codieren. Beim Schreiben (oder Aktualisieren) von Dateien würde ich dann zu der Gebietsschema-Codierung zurückdecodieren.

+1

Sie haben einen Punkt falsch in Ihrer Antwort oben. Perl nimmt standardmäßig 8-Bit-Latin-1 für die Codierung von Zeichenfolgen an. Wie bei Shift-JIS ist Latin-1 eine Obermenge von ASCII. –

+0

Ihre Stimme hat mir Kommentare gegeben. Vielen Dank! – Lozzer

+0

Entschuldigung für den obigen Fehler. Ja, es ist Latin 1. Der Hauptpunkt ist jedoch Perls Verwendung von UTF8, die Pfadnamen auf Windows-Systemen vermasselt. Ich finde es immer noch erstaunlich, dass man in Perl (auf nicht-lateinischen Windows-Systemen) keinen einfachen "open" -Befehl verwenden kann, ohne sich mit Win32 :: Codepage herumzuärgern. – Lozzer

0

Ich entdeckte, dass ich UAC (User Access Control) auf Microsoft Windows Vista deaktivieren musste, bevor ich Win32::Locale oder Win32::Codepage erfolgreich installieren konnte. (Danke, Chris Dolan, für das Schreiben des letzteren Moduls.)

0

Ich hatte auch Probleme mit UAC (User Access Control) unter Windows 7 und neuer. Ich habe schließlich herausgefunden, dass der Zugriff auf den erforderlichen Registrierungsschlüssel nur Leseberechtigungen seit Windows Vista hat. Sie können ganz einfach Win32 Patch :: Codepage ohne Administratorrechte zu arbeiten, wenn Sie die Datei in einem Editor öffnen und ersetzen:

$codekey = Win32::TieRegistry->new($CODEPAGE_REGISTRY_KEY, 
            { Delimiter => "/" } 
            ); 

    $codekey = Win32::TieRegistry->new($CODEPAGE_REGISTRY_KEY, 
            { Access=>"KEY_READ", Delimiter => "/" } 
            ); 

Diese auf meiner Installation geholfen haben.

+1

Was hat das mit akzentuierten Zeichen in Dateipfaden zu tun? –

Verwandte Themen