Filesystem encoding ermitteln?

Alles, was PHP betrifft, kann hier besprochen werden.

Filesystem encoding ermitteln?

Postby ollo » 22. June 2008 11:12

Hallöchen Forum.

Weiß jemand wie man die korrekte Zeichensatzkodierung des Filesystems ermitteln kann?

Ich habe eine Applikation die MP3s einliest (also nur die Tags) und dann über Weboberfläche abrufbar macht. Dazu klappere ich ein bestimmtes Verzeichnis ab und speichere die Informationen in MySQL, inklusive Ordner-/Dateinamen natürlich.

Da das komplette Backend auf UTF8 basiert, konvertiere ich derzeit statisch mittels iconv() von Windows-1252 nach UTF8 (beim Abruf dann umgekehrt). Das funktioniert soweit ganz gut auch mit deutschen Umlauten, aber es gibt Probleme bspw. mit kyrillischen Zeichen oder Sonderzeichen wie dem 'Kreuz'.

Abgesehen von der statischen Zuordnung würde es damit auch Probleme unter Linux und anderen OS geben, da die teilweise beliebige Kodierungen verwenden können.

Also, kann man dem aktuell verwendeten Filesystem irgendwie die Kodierung entlocken? Oder kann auch etwas anderes die Ursache sein?
ollo
 
Posts: 85
Joined: 11. November 2004 12:29

Postby Wiedmann » 22. June 2008 13:31

Fangen wir mal anders an:
Wie kommen die Dateien mit diesen Dateinamen auf den Server und greifst du auch auf dem Server selbst mit richtigen Windowsprogrammen auf diese Dateien zu?

(aber um es vorwegzunehmen: PHP kann mit dem Windowsdateisystem nicht korrekt umgehen)
Wiedmann
AF Moderator
 
Posts: 17102
Joined: 01. February 2004 12:38
Location: Stuttgart / Germany

Postby ollo » 22. June 2008 15:11

Also derzeit liegt hier noch alles lokal, also XAMPP läuft hier auf meinem Desktop und die Dateien ebenfalls, bzw. auf einem Netzlaufwerk. Letzteres habe ich nicht ausgiebeig durchgetestet, aber ein Import lief wie erwartet durch (wegen dem quälend langsamen Server bin ich dann aber auf komplett lokal umgestiegen).

In Zukunft (externer Server) werden die Dateien entweder per FTP (ich sehe Probleme am Horizont) oder auch per CIFS (will VPN nutzen) aufgespielt.

Aber das Grundproblem bleibt das gleiche, oder? Immerhin kann man unter Linux das Encoding doch frei wählen, also entweder ist es schon UTF8 oder irgend was anderes, ergo muss ich wissen was da reinkommt, richtig?

Aber was du sagst bringt mich auf etwas... ein Album mit dem Titel "Cross" (also ein Kreuz als Sonderzeichen) wurde offenbar korrekt eingefügt, in der DB bzw im Frontend sieht man das Kreuz. Allerdings kann er nicht auf die Dateien zugreifen, es scheint also beim Konvertieren von UTF8 --> Windows zu knallen. Dummerweise findet man da auch keine vernünftigen Infos zu, eine Quelle meinte NTFS nutzt schon UTF8, ohne Konvertierung funktionierte es aber nicht.

Irgendwelche Tipps?
ollo
 
Posts: 85
Joined: 11. November 2004 12:29

Postby Wiedmann » 22. June 2008 15:43

Aber was du sagst bringt mich auf etwas... ein Album mit dem Titel "Cross" (also ein Kreuz als Sonderzeichen) wurde offenbar korrekt eingefügt, in der DB bzw im Frontend sieht man das Kreuz. Allerdings kann er nicht auf die Dateien zugreifen, es scheint also beim Konvertieren von UTF8 --> Windows zu knallen. Dummerweise findet man da auch keine vernünftigen Infos zu, eine Quelle meinte NTFS nutzt schon UTF8, ohne Konvertierung funktionierte es aber nicht.

Lass es mich so sagen:
Ein Dateiname den PHP anlegt, kann es auch selbst wieder lesen. Du musst also nur dafür sorgen, dass die Dateinamen (Strings in PHP) 'utf-8' kodiert sind. Das funktionert dann mit jedem OS/Dateisystem.

Unter Windows sieht ein echtes Windowsprogramm bei diesen Dateinamen dagegen nur Murx, kann sie aber öffnen. Mit einer Datei mit einem richtigen Unicodedateinamen, von einem Windowsprogramm erzeugt, kann PHP dagegen gar nichts anfangen). Da du ja aber eine Webanwendungen schreiben willst, ist das ja hier normal vernachlässigbar.
Wiedmann
AF Moderator
 
Posts: 17102
Joined: 01. February 2004 12:38
Location: Stuttgart / Germany

Postby ollo » 23. June 2008 00:09

Wiedmann wrote:Lass es mich so sagen:
Ein Dateiname den PHP anlegt, kann es auch selbst wieder lesen. Du musst also nur dafür sorgen, dass die Dateinamen (Strings in PHP) 'utf-8' kodiert sind. Das funktionert dann mit jedem OS/Dateisystem.


Hm, was heißt das nun genau? Prinzipiell ist der benötigte Weg ja:

Filesystem, scandir (?)
--> PHP (UTF-8 )
--> MySQL (UTF-8 )
--> PHP (UTF-8 )
--> Filesystem, fopen etc. (?)

Nur bei MySQL bin ich mir sicher dass die gespeicherten Strings UTF8 sind, bislang funktioniert auch alles, bspw. wenn ich in einer Form Japanisches UTF-8 eingebe oder Lautschrift oder Arabisch. Es wird korrekt gespeichert, gelesen und ausgegeben (über Umweg XML-XSLT).

Also scheint die gesamte interne Verarbeitung zu funktionieren, interessanterweise ist bei mir allerdings kein 'internal_encoding' gesetzt. Doch das dürfte ja nur einen Effekt haben bei strlen() und Konsorten, dachte ich zumindest?

Der Witz ist ja, dass es bei äöü funktioniert, das heißt ja dass prinzipiell der Part FS --> UTF-8 --> FS funktioniert, denn die Umlaute haben ja in UTF-8 eine vollkommen andere Kodierung als in ISO, Windows etc.
Und auf diesem Weg mache ich zwei mal iconv(), von Windows1251 nach UTF-8 und zurück.

Mit dem 'Cross' muss ich noch mal schauen, da könnte auch etwas anderes passieren, denn er speichert den Namen des Albums korrekt, nur der Dateiname (in dem das 'Cross' wieder vorkommt) scheint kein UTF-8 zu sein (Ausgabe zeigt FF3-Hex-Rechteck statt 'Cross').

Aber interessant sind die kyrillischen Zeichen, wenn ich das Array von scandir() direkt wieder dumpe, sind alle solchen Zeichen zu Fragezeichen mutiert. Unabhängig vom Encoding für die Seite wohlgemerkt...

Unter Windows sieht ein echtes Windowsprogramm bei diesen Dateinamen dagegen nur Murx, kann sie aber öffnen. Mit einer Datei mit einem richtigen Unicodedateinamen, von einem Windowsprogramm erzeugt, kann PHP dagegen gar nichts anfangen). Da du ja aber eine Webanwendungen schreiben willst, ist das ja hier normal vernachlässigbar.


Also getaggt und benannt werden die MP3s derzeit mit Mp3Tag, danach irgendwie auf den Server geladen, ab da greift PHP zum Katalogisieren.

Aber irgendwie verstehe ich den Absatz von Dir nicht ganz. Bedeutet das, dass Windows resp. NTFS kein festes Encoding hat? Also dass per default im Windows1251 Encoding benannt wird, aber pro Datei die Option besteht ein anderes Encoding (UTF-8, oder weitere?) zu verwenden?

Das würde vielleicht das komische Verhalten teilweise erklären, denn die kyrillischen Zeichen wurden von o.g. Tool vom Tag in den Dateinamen übernommen. Das 'Cross' wurde nur bei den MP3s selbst von dem Tool erzeugt, vielleicht auch ein Indiz für das Unterschiedliche Verhalten von Order und Dateien...

So, viel schlauer bin ich jetzt leider auch nicht... :) :(
ollo
 
Posts: 85
Joined: 11. November 2004 12:29

Postby Wiedmann » 23. June 2008 10:00

Filesystem, scandir (?)
...
Also getaggt und benannt werden die MP3s derzeit mit Mp3Tag, danach irgendwie auf den Server geladen, ab da greift PHP zum Katalogisieren.

Eben hier liegt wie gesagt dein Problem:
Die (Unicode-) Dateinamen werden (korrekt) von einem Windowsprogram erzeugt. Also gibt es bei solchen Namen für PHP keine Möglichkeit auf diese zuzugreifen (Scandir/fopen,...).

Aber irgendwie verstehe ich den Absatz von Dir nicht ganz.

Na ist doch ganz einfach ;-) Lass die Dateinamen (utf-8-Strings) von PHP erzeugen.
(Oder benutzte als Dateinamen nur Zeichen aus ASCII)

Es werden dann für ein UTF-8 Zeichen zwei CP1252 Zeichen geschrieben. Sieht im Explorer bescheuert aus, aber PHP selbst kann das hinterher wieder lesen.
(Probleme gibt es hier nur, wenn du dann hinterher z.B. direkt über einen Browser/Apache wieder darauf zugreifen willst, ohne über PHP zu gehen.)


Bedeutet das, dass Windows resp. NTFS kein festes Encoding hat?

Das wäre dann *nix.

Also dass per default im Windows1251 Encoding benannt wird, aber pro Datei die Option besteht ein anderes Encoding (UTF-8, oder weitere?) zu verwenden?

Im NTFS- (und FAT32-) Dateisystem werden alle Dateinamen Unicode (UCS-2) kodiert abgespeichert.

Also C/C++ Programmierer gibt es dann zwei Möglichkeiten auf das Dateisystem zuzugreifen:
a) man benutzt die Funktionen, die nur die aktuelle Codepage von Windows verwenden können. (Bei einer westeuropäischen Windowsinstallation wäre das dann Windows-1252). Windows intern wird dann von der aktuellen Codepage noch Unicode umkodiert und zurück. b) man benutzt gleich die Funktionen, die den kompletten Unicode-Zeichensatz benutzen können.

PHP arbeitet nach a).
Wiedmann
AF Moderator
 
Posts: 17102
Joined: 01. February 2004 12:38
Location: Stuttgart / Germany

Postby Wiedmann » 23. June 2008 11:32

Wiedmann wrote:Die (Unicode-) Dateinamen werden (korrekt) von einem Windowsprogram erzeugt. Also gibt es bei solchen Namen für PHP keine Möglichkeit auf diese zuzugreifen (Scandir/fopen,...).

Eine Möglichkeit gibt es allerdings doch:
Über die COM-Extension und dem "Scripting.FileSystemObject" kannst du auch mit PHP auf die Unicode-Dateinamen zugreifen und dir somit eine korrekte Liste erstellen.
Wiedmann
AF Moderator
 
Posts: 17102
Joined: 01. February 2004 12:38
Location: Stuttgart / Germany

Postby ollo » 30. June 2008 20:19

Wiedmann wrote:Eben hier liegt wie gesagt dein Problem:
Die (Unicode-) Dateinamen werden (korrekt) von einem Windowsprogram erzeugt. Also gibt es bei solchen Namen für PHP keine Möglichkeit auf diese zuzugreifen (Scandir/fopen,...).


Ngr. Soweit so schlecht...

Na ist doch ganz einfach ;-) Lass die Dateinamen (utf-8-Strings) von PHP erzeugen.
(Oder benutzte als Dateinamen nur Zeichen aus ASCII)

Es werden dann für ein UTF-8 Zeichen zwei CP1252 Zeichen geschrieben. Sieht im Explorer bescheuert aus, aber PHP selbst kann das hinterher wieder lesen.
(Probleme gibt es hier nur, wenn du dann hinterher z.B. direkt über einen Browser/Apache wieder darauf zugreifen willst, ohne über PHP zu gehen.)


Ngraangaa! Warum zur Hölle hat man nur ASCII und das andere Kodierungsgesocks vor UTF-8 erfunden, wär's umgekehrt hätten wir heute eine gefühlte Millarde Probleme weniger...

Also mit PHP erzeugen ist m.E. momentan keine Option. Bleibt also nur ASCII (Track1.mp3 oder etwas ähnlich blödes). Vielleicht teste ich mal die Option mit ActiveX, aber da ist die Frage ob dieses immer verfügbar ist.

Bedeutet das, dass Windows resp. NTFS kein festes Encoding hat?

Das wäre dann *nix.


Was ich allerdings nicht verstehe: ich MUSS, bevor ich die Ordner-/Dateinamen in die DB einfüge, eine Konvertierung von Windows-1252 nach UTF-8 machen, und vor dem Öffnen wieder zurück. Sonst stimmen die Namen in der DB nicht (kein UTF-8 ), und die Dateien können nicht geöffnet werden.

Wenn ich das richtig verstehe, wäre das nach der von Dir beschriebenen Logik doch gar nicht nötig. Und es bringt mich wieder zum Ursprungsproblem zurück, wie erkenne ich das Encoding der von scandir() gelieferten Namen? Denn unter Linux muss ich das ja wissen, da es kein festgelegtes Encoding gibt...

Unter Windows bleibt das Problem aber auch teilweise bestehen, da ich nicht mit Sicherheit sagen kann dass die öäü von Windows mit Westeuropäischer Codepage erzeugt wurden. Wobei ich darauf zähle, dass in allen lokalen Codepages diese Umlaute die gleiche Kodierung besitzen.

Ach Mist, ich glaube ich komme um ActiveX aber nicht herum, denn was ist wenn ein Chinese seine Folklore-Songs importieren will? :evil:
ollo
 
Posts: 85
Joined: 11. November 2004 12:29


Return to PHP

Who is online

Users browsing this forum: No registered users and 12 guests