Verwendung von zlib mit Unicode-Dateipfaden unter Windows

7

Ich lese gzip komprimierte Dateien mit zlib. Dann öffnest du eine Datei mit

%Vor%

Wie gehen Sie mit Unicode-Dateipfaden um, die als const wchar_t* unter Windows gespeichert sind?

Auf UNIX-ähnlichen Plattformen können Sie einfach den Dateipfad in UTF-8 konvertieren und gzopen () aufrufen, aber das wird unter Windows nicht funktionieren.

    
user763305 15.03.2012, 09:34
quelle

5 Antworten

11

Die nächste Version von zlib enthält diese Funktion, wobei _WIN32 #defined ist:

gzFile gzopen_w(const wchar_t *path, char *mode);

Es funktioniert genau wie gzopen() , außer dass _wopen() anstelle von open() verwendet wird.

Ich habe absichtlich das zweite Argument von _wfopen() nicht dupliziert und deshalb habe ich es nicht _wgzopen() genannt, um mögliche Verwechslungen mit den Argumenten dieser Funktion zu vermeiden. Daher der Name gzopen_w() . Das vermeidet auch die Verwendung des C-reservierten Namensraums.

    
Mark Adler 17.03.2012, 03:07
quelle
11

Zu allererst, was ist ein Dateiname?

Auf Unix-ähnlichen Systemen

Ein Dateiname ist eine Bytefolge , die mit Null abgeschlossen wird. Der Kernel muss sich nicht um die Zeichencodierung kümmern (außer dass er den ASCII-Code für / kennt).

Aus Sicht des Benutzers ist es jedoch bequemer, Dateinamen als Folgen von Zeichen zu interpretieren. Dies geschieht durch eine Zeichencodierung, die als Teil des Gebietsschemas angegeben ist >. Unicode wird unterstützt , indem UTF-8-Ländereinstellungen verfügbar gemacht werden.

In C-Programmen werden Dateien mit normalen char* strings in Funktionen wie fopen dargestellt. Es gibt keine Wide-Character-Version der POSIX-API. Wenn Sie einen wchar_t* -Dateinamen haben, müssen Sie ihn explizit in ein char* konvertieren.

Unter Windows NT

Ein Dateiname ist eine Sequenz von UTF-16-Code-Einheiten . Tatsächlich wird die all Zeichenfolgenbearbeitung in Windows intern in UTF-16 durchgeführt.

Alle C (++) -Bibliotheken von Microsoft, einschließlich der Visual C ++ - Laufzeitbibliothek, verwenden die Konvention, dass char* -Strings in der länderspezifischen ANSI-Codepage stehen und wchar_t* -Strings in UTF sind. 16. Und die char* -Funktionen sind nur Abwärtskompatibilitäts-Wrapper um die neuen wchar_t* -Funktionen.

Also, wenn Sie MessageBoxA(hwnd, text, caption, type) , das ist im Wesentlichen das gleiche wie den Aufruf von MessageBoxW(hwnd, ToUTF16(text), ToUTF16(caption), type) . Und wenn Sie fopen(filename, mode) aufrufen, ist das wie _wfopen(ToUTF16(filename), ToUTF16(mode)) .

Beachten Sie, dass _wfopen eine der vielen nicht standardmäßigen C-Funktionen für das Arbeiten mit wchar_t* strings ist. Und das ist nicht nur aus Bequemlichkeit; Sie können die standardmäßigen char* -Äquivalente nicht verwenden, da sie Sie auf die "ANSI" -Codepage beschränken (wobei kann nicht UTF-8 sein ). Zum Beispiel können Sie in einem Windows-1252-Gebietsschema nicht (einfach) fopen der Datei שלום.c zuordnen, da es keine Möglichkeit gibt, diese Zeichen in einer schmalen Zeichenfolge darzustellen.

In plattformübergreifenden Bibliotheken

Einige typische Ansätze sind:

  1. Verwenden Sie Standard-C-Funktionen mit char* -Zeichenfolgen, und geben Sie keine
dan04 16.03.2012 04:11
quelle
4

Sie haben die folgenden Optionen

%Vor%
  1. Patch zlib, so dass es _wfopen unter Windows und nicht fopen verwendet. Verwenden Sie dazu etwas ähnliches wie oben in zutil.h

  2. Verwenden Sie _wfopen oder _wopen anstelle von gzopen und übergeben Sie den Rückgabewert an gzdopen .

  3. Verwenden Sie libiconv oder eine andere Bibliothek, um die zu konvertierende Datei aus Ihrer angegebenen Unicode-Codierung in ASCII zu ändern, und übergeben Sie die ASCII-Zeichenfolge an gzopen. Wenn libiconv fehlschlägt, behandeln Sie den Fehler und fordern den Benutzer auf, die Datei umzubenennen.

Weitere Informationen zu iconv finden Sie unter Ein Beispiel für iconv . In diesem Beispiel wird Japanisch zu UTF-8 verwendet, aber es wäre kein großer Schritt, die Zielcodierung in ASCII oder ISO 8859-1 zu ändern.

Weitere Informationen zur Konvertierung von zlib und nicht-ANSI-Zeichen finden Sie hier

    
Appleman1234 15.03.2012 21:23
quelle
3

Hier ist eine Implementierung von Applemans Option # 2. Der Code wurde getestet.

%Vor%

Ich habe beide gemacht filename und mode const wchar_t* für die Konsistenz mit Windows-Funktionen wie

%Vor%     
user763305 16.03.2012 06:57
quelle
0

Hier ist meine eigene Version der Unicode-Hilfsfunktion, etwas besser als die obige Version getestet.

%Vor%     
TarmoPikaro 26.10.2015 20:32
quelle

Tags und Links