Unicode file names



  • Hallo,

    ich schlage mich seit einigen Tagen durch die Man-Pages und weiteren Artikeln. Mein aktueller Kentnissstand ist
    - Windows nutzt UTF-16 für File-Namen
    - Linux, ähhm ja
    + geht man von der C-API aus, dann max. UTF-8 (z.B. fopen (char*))
    + was ist mit wchar_t? Ist ja im GCC mit 32bit hinterlegt. Also UTF-32 möglich

    Was ist nun auf Linux möglich?
    Wie erstellt/öffent man eine Dateinamen mit UTF-16 Codierung in Linux?

    Gruß, Thomas



  • fopen() ist Standard C und kennt grundsätzlich (auch unter Windows) nur ANSI-Strings. Aber: http://stackoverflow.com/questions/2304077/how-do-i-create-a-unicode-filename-in-linux

    MfG SideWinder



  • fopen unter Linux nimmt einfach nur einen C-String und kümmert sich nicht um das Encoding. Solange dein UTF-16 kein 0-byte enthält, kannst du das einfach als Dateinamen nehmen. Aber warum willst du unter Linux UTF-16 Dateinamen? Das ergibt einfach keinen Sinn. Unter Linux nimmt man für Unicode in der Regel UTF-8. Auch die Linux-NTFS-Treiber (zB NTFS-3G) wandeln die Dateinamen in UTF-8 um.



  • rüdiger schrieb:

    Aber warum willst du unter Linux UTF-16 Dateinamen? Das ergibt einfach keinen Sinn. Unter Linux nimmt man für Unicode in der Regel UTF-8. Auch die Linux-NTFS-Treiber (zB NTFS-3G) wandeln die Dateinamen in UTF-8 um.

    Ich frage mich zur Zeit, wieso der GCC wchar_t mit 32bit unterstützt und wchar_t nicht für die IO-Library implementiert wurde.



  • Siassei schrieb:

    Ich frage mich zur Zeit, wieso der GCC wchar_t mit 32bit unterstützt und wchar_t nicht für die IO-Library implementiert wurde.

    Vermutlich weil es so ist, wie ruediger geschrieben hat: Linux-Dateisysteme und der Linux-Kernel kümmern sich nicht ums Encoding, die akzeptieren als Dateinamen beliebige Bytefolgen. Die einzige Ausnahme ist, dass ein Dateiname kein Null-Byte enthalten darf, das ist aber auch tatsächlich die einzige Ausnahme.

    Strings in UTF-16 können Null-Bytes enthalten, und Strings in UTF-32 sowieso. Deswegen kannst du auf Linux-Dateisystemen keine Dateinamen in UTF-16 oder UTF-32 ablegen, wegen der Regel "keine Null-Bytes". UTF-32 in der API wär also zum einen Verschwendung, weil ständig umkodiert werden müsste, zum anderen würde es die Linux-Konvention "der Kernel kümmert sich nicht um Encodings" brechen.

    Strings in UTF-8 dagegen enthalten garantiert keine Null-Bytes, deswegen bieten die sich unter Linux für Dateinamen an. Aber auch das wird durch nichts gefordert außer durch Konvention. Du kannst ohne weiteres auf jedem Linux-System eine Datei anlegen, deren Dateiname SJIS-kodiert ist. Programme, die UTF-8 erwarten, werden so einen Dateinamen dann einfach nicht richtig anzeigen und ls wird ihn ziemlich sicher durch eine Reihe von Fragezeichen ersetzen. Aber der Dateiname wird so wie er ist auf die Festplatte geschrieben. Ob es gültiges UTF-8 ist, prüft unter Linux niemand.



  • Siassei schrieb:

    rüdiger schrieb:

    Aber warum willst du unter Linux UTF-16 Dateinamen? Das ergibt einfach keinen Sinn. Unter Linux nimmt man für Unicode in der Regel UTF-8. Auch die Linux-NTFS-Treiber (zB NTFS-3G) wandeln die Dateinamen in UTF-8 um.

    Ich frage mich zur Zeit, wieso der GCC wchar_t mit 32bit unterstützt und wchar_t nicht für die IO-Library implementiert wurde.

    Ist es doch, wenn du wcout etc. meinst. Nur eben nicht für Dateinamen. Aber das wird vom Standard auch nicht gefordert. wchar_t ist sowieso ein Chaos: Auf einigen Systemen sind es UCS2 Codepoints, auf anderen UTF16 und dann ist es wieder UTF32. In C++0x gibt es char16/32_t. Aber ich würde trotzdem einfach UTF8 nehmen und unter Windows dann bei Syscalls konvertieren.



  • rüdiger schrieb:

    Aber ich würde trotzdem einfach UTF8 nehmen und unter Windows dann bei Syscalls konvertieren.

    Man darf aber unter unter Linux wiederum die Dateinamen auch nicht nach UTF-8 (oder sonstwas) konvertieren! Die Original-Bytesequenz muss erhalten bleiben.

    Da wurde mir neulich schmerzhaft bewusst, dass es in QT scheinbar keine korrekte Art gibt, ein Verzeichnis zu lesen.

    Siehe http://doc.qt.nokia.com/latest/qdir.html#entryList
    Der Dateiname wird, je nach gesetzter locale, erstmal nach QStrings unicode kodiert 😞
    Dadurch sieht er zwar meist am Bildschirm gut aus, auf die Datei kann man aber nicht mehr sicher zugreifen.



  • @DrGreenthumb:
    So lange beim "Umwandeln" nicht normalisiert wird, sehe ich jetzt kein Problem...
    Oder gibt es Dinge die einen Round-Trip UTF-8 -> UTF-16 -> UTF-8 bzw. UTF-8 -> UTF-32 -> UTF-8 nicht überleben?

    OK... Byte-Sequenzen die kein gültiges UTF-8 darstellen wären wohl ein Problem.



  • Geht glaube ich eher um ISO 8859-X zu UTF-8. Unter Linux sollte man eigentlich nichts mit UTF-16 Dateinamen zu tun haben (wie gesagt, die NTFS-Treiber wandeln die Dateinamen idR in UTF-8 um. Sonst wären die in den meisten Terminals nicht richtig darstellbar).



  • hustbaer schrieb:

    @DrGreenthumb:
    So lange beim "Umwandeln" nicht normalisiert wird, sehe ich jetzt kein Problem...
    Oder gibt es Dinge die einen Round-Trip UTF-8 -> UTF-16 -> UTF-8 bzw. UTF-8 -> UTF-32 -> UTF-8 nicht überleben?

    OK... Byte-Sequenzen die kein gültiges UTF-8 darstellen wären wohl ein Problem.

    das ist das Problem. Wenn die Quelle schon undefiniert ist, kann auch nicht korrekt wieder zurückkonvertiert werden.



  • DrGreenthumb schrieb:

    hustbaer schrieb:

    @DrGreenthumb:
    So lange beim "Umwandeln" nicht normalisiert wird, sehe ich jetzt kein Problem...
    Oder gibt es Dinge die einen Round-Trip UTF-8 -> UTF-16 -> UTF-8 bzw. UTF-8 -> UTF-32 -> UTF-8 nicht überleben?

    OK... Byte-Sequenzen die kein gültiges UTF-8 darstellen wären wohl ein Problem.

    das ist das Problem. Wenn die Quelle schon undefiniert ist, kann auch nicht korrekt wieder zurückkonvertiert werden.

    Ist aber auch nur ein Problem, weil die Transformation UTF-8 -> UTF-XX -> UTF-8 für beliebige Bytefolgen nicht 100% verlustfrei ist.
    Wäre sie das (verlustfrei), dann wäre die "undefinierte Quelle" auch kein Problem.


Anmelden zum Antworten