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.
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.
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.
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)
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.
Einige typische Ansätze sind:
char*
-Zeichenfolgen, und geben Sie keine Sie haben die folgenden Optionen
%Vor% Patch zlib, so dass es _wfopen
unter Windows und nicht fopen
verwendet. Verwenden Sie dazu etwas ähnliches wie oben in zutil.h
Verwenden Sie _wfopen
oder _wopen
anstelle von gzopen und übergeben Sie den Rückgabewert an gzdopen
.
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
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
Hier ist meine eigene Version der Unicode-Hilfsfunktion, etwas besser als die obige Version getestet.
%Vor%