On Sat 11 Apr 2009, Sebastian Reinhardt wrote:
aber der Quatsch mit den Kodierungen, da sehe ich nun gar nicht mehr durch.
Es ist zugegeben nicht einfach, sich in die UTF8 Materie in Perl einzuarbeiten. Das hat historische Gründe. Perl war/ist erstmal eine Byte- oder Octet-orientierte Sprache. UTF8 wurde später dazugebaut und man wollte natürlich kompatibel bleiben. Entsprechend kompliziert ist das Resultat. Die unterschiedlichen Betriebssysteme machen es auch nicht einfacher. Um bei den Verzeichniseinträgen zu bleiben, angenommen Du benutzt die deutsche Standardinstallation Deines opensuse 11.0, dann sind die Verzeichniseinträge UTF8 kodiert. Ein "touch ö" erzeugt eine Datei mit dem Namen "ö". Mach das mal in einem leeren Verzeichnis. Danach machst Du in diesem Verzeichnis "echo *|wc -c". Du wirst eine 3 sehen. Das ist richtig, denn der Dateiname besteht aus 2 Bytes, plus das \n, das "echo" anfügt. Dann machst Du "echo *|wc -m", das zählt Buchstaben, nicht Bytes, und Du erhältst eine 2, auch richtig. Doch nun machst Du "echo *|LANG=C wc -m" und erhältst wieder eine 3, wieso? Offensichtlich hat die Umgebungsvariable LANG Einfluß darauf, wie die Namen Verzeichniseinträgen angezeigt werden. Anderer Versuch, probier mal sowas: LANG=C xterm -e 'ls -l; sleep 30' In dem Terminal-Fenster erscheint das hier: -rw-r--r-- 1 r2 users 0 Apr 11 10:41 ?? Häh, ich hatte doch "touch ö" gesagt, wieso zeigt er mir den Namen als "??" an? Übrigens, mit LANG=de_DE kommt das hier raus: -rw-r--r-- 1 r2 users 0 11. Apr 10:41 ö Erst mit einer LANG Variablen, die .utf8 enthält, z.B. LANG=de_DE.utf8, siehst Du das "ö". Es kommt also darauf an, wie man auf die Bytes guckt. Das selbe Problem hat Perl auch. Es kennt nicht von sich aus die Kodierung eines Strings, der Bytes >0x7f enthält. Wenn Du in Perl mit UTF8 arbeiten willst mußt Du im Prinzip 3 Fragen stellen: 1) Sind die zu verarbeitenden Daten, egal ob Input oder Output, Zeichen oder Bytes? 2) Welche Kodierung habe ich am Input, denn alle Daten, die in mein Programm reinkommen, müssen internalisiert werden, d.h. von ihrer irgendwie gearteten Kodierung in Perl's interne Zeichendarstellung gewandelt werden. 3) Welche Kodierung erwartet der Empfänger der Daten, die ich ausgebe? Alle Daten, die ich ausgebe, müssen in dieses Format gebracht werden. Diese Fragen mußt Du für jeden Datenstrom einzeln stellen. Das readdir Resultat ist bei Dir ein solcher Strom, ein anderer ist der Input vom Browser, das was CGI liest. Der 3. Strom ist Dein Output an den Browser. Für den 3. Strom kannst Du zum Glück dem Browser mitteilen, was er zu erwarten hat (charset im Content-Type). Bei den beiden anderen mußt Du raten. Sagst Du dem Browser, daß Du UTF8 lieferst, mußt Du das auch tun, entweder über binmode(STDOUT, ":encoding(UTF-8)") oder eben print "...", Encode::encode("utf8", $value), "..." Gehst Du davon aus, daß der Browser UTF8 an Dich schickt, kannst Du es entweder dem CGI-Modul sagen: use CGI qw/-utf8/; oder Du internalisierst die Daten selbst: my $param=Encode::decode 'utf8', CGI::param('Parameter') Beim Lesen des Verzeichnisses gibt es nur die Methode, es selbst zu machen: my @eintraege=map {Encode::decode 'utf8', $_} readdir DIR Wenn Du in Deinem Programm String-Konstanten benutzt, die Umlaute enthalten und wenn Dein Editor diese UTF8-kodiert, mußt Du das dem Interpreter auch sagen: use utf8; Wenn ich WEB-Programme schreibe, die UTF8 können sollen, gibt es bei mir immer einen ie-Parameter, für "input encoding", und meist auch einen oe-Parameter, für "output encoding". Wenn Du Dich dann an die obigen Regeln hältst, ist das Programm universell einsetzbar. Unabhängig davon mußt Du natürlich richtiges HTML schreiben und dazu gehört, daß hrefs URL-encoded sind. Kombiniert mit UTF8 Output würde das so aussehen: uri_escape Encode::encode('utf8', "$verzeichnis/$eintrag") Torsten -- Need professional mod_perl support? Just hire me: torsten.foertsch@gmx.net -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: opensuse-de+help@opensuse.org