Je lis, je lisez des fichiers compressés gzip en utilisant zlib.
Ensuite, vous ouvrez un fichier en utilisant Comment gérez-vous des chemins de fichiers unicode stockés sous forme sur UNIX -Les plates-formes simples, vous pouvez simplement convertir le chemin de fichier en UTF-8 et appeler gzopen (),
Mais cela ne fonctionnera pas sur Windows. p> p> const wchar_t * code> sous Windows? P>
5 Réponses :
Vous avez les options suivantes
#ifdef _WIN32 #define F_OPEN(name, mode) _wfopen((name), (mode)) #endif
Quelqu'un peut-il aider à déchiffrer ce que ici i> Lien pointé sur?
La page ne semble pas être archivée sur archive.org, je pense que c'était un poste sur les anciens forums de développement BSNES, élaborant davantage sur le travail effectué sous l'élément de ligne - ZLIB modifié pour prendre en charge les caractères non-ANSI de BSNES Changelog. static.hexostum.net/bsnes/bsnes_changelog.txt
Un nom de fichier est une séquence d'octets strong> terminé par zéro. Le noyau n'a pas besoin de se soucier de l'encodage des caractères (sauf pour connaître le code ASCII Cependant, il est plus pratique du point de vue des utilisateurs d'interpréter les noms de fichiers sous forme de séquences de caractères em>, et cela se fait par un caractère encodage spécifié dans le cadre de la locale strong >. Unicode est pris en charge en faisant UTF-8 locales disponibles . p>
Dans les programmes C, les fichiers sont représentés avec ordinaire Un nom de fichier est une séquence d'unités de code UTF-16 strong>. En fait, tous em> manipulation de chaînes dans Windows se fait en UTF-16 en interne. P>
Toutes les bibliothèques C (++) de Microsoft, y compris la bibliothèque d'exécution Visual C ++, utilisez la convention que Alors, si vous appelez Notez que Certaines approches typiques sont: p>
Malheureusement, il semble utiliser l'approche naïve 1 ci-dessus, avec En plus des solutions déjà mentionnées (mon préféré qui est / code>). P>
char * code> chaînes strong> dans des fonctions comme
fopen code>. Il n'y a pas de version grand caractère de l'API Posix. Strong> Si vous avez un
wchar_t * code> nom de fichier, vous devez explicitement le convertir en un
char * code> . p>
Sous Windows NT h2>
char * code> chaînes sont dans l'héritage local spécifique "ANSI" page de code et le code < > wchar_t * code> chaînes sont en UTF-16. Et le
char * code> fonctions ne sont que des enveloppes de compatibilité ascendante dans le nouveau
wchar_t * code> fonctions. P>
MessageBoxA (hwnd, texte, légende, type) code>
, qui est essentiellement le même que d'appeler MessageBoxW (hwnd, ToUTF16 (texte), ToUTF16 (légende), type) code>. Et lorsque vous appelez
fopen (nom de fichier, Mode) code>
, qui est comme _wfopen (ToUTF16 (nom de fichier), ToUTF16 (mode)) code>. p>
_wfopen code> est l'un des de nombreuses fonctions non standard C pour travailler avec
wchar_t * code> chaînes strong>. Et ce n'est pas seulement pour la commodité; ne peut pas em> utiliser le standard
char * code> équivalent strong> parce qu'ils vous limiter à la page de code "ANSI" (qui ne peut pas être UTF-8 ). Par exemple, dans un lieu de Windows 1252, vous ne pouvez pas (facilement)
fopen code> le fichier
שלום. C code>, parce qu'il n'y a aucun moyen de représenter ces personnages dans une étroite string. p>
Dans les bibliothèques multi-plateforme h2>
char * code> chaînes, et juste ne donnent pas un 💩 sur le support des caractères non-ANSI sous Windows. Li>
char * code> chaînes mais les interpréter comme UTF-8 au lieu de la norme ANSI. Sous Windows, écriture wrapper fonctions qui prennent UTF-8 arguments, les convertir en UTF-16 et les fonctions d'appel comme
_wfopen code>. Li>
Comment les noms de fichiers poignée zlib? H1>
open code> (plutôt que
_wopen code>) utilisé directement. P>
Comment pouvez-vous travailler autour d'elle? H1>
de Appleman1234 gzdopen code> suggestion), vous pouvez profiter de nom court . P >
Il y a donc deux approches pour Zlib. Soit A) avoir gzopen () effectuez toujours la conversion UTF-8 à UTF-16 sur Windows et utilisez _wopen () ou b) laissez gzopen () comme utilise ouverte () et ajoutez une nouvelle fonction _wgzopen () uniquement sur Windows qui prend un argument UTF-16 et utilise _wopen (). Quelle serait la recommandation de DAN04?
@Mark: Vous ne devez pas vous demander si la bibliothèque GZIP doit utiliser ceci ou ce codage. La bibliothèque ne doit pas décider quel codage à utiliser. C'est la responsabilité de l'application qui utilise la bibliothèque. L'application fait généralement cela en définissant la locale actuelle. La bibliothèque doit simplement utiliser les codages spécifiés par la locale actuelle. Le moyen le plus simple de le faire est de déléguer aux fonctions sensibles aux paramètres régionaux existants, comme dans votre alternative B).
@Markadler: Pour ME I>, il serait plus pratique si Zlib a utilisé UTF-8, car c'est ce que la norme de codage de ma équipe nécessite (principalement pour des raisons de compatibilité avec d'autres bibliothèques tiers telles que SQLite et Tinyxml). Peut-être que vous pourriez fournir des versions UTF-8 et UTF-16 des fonctions.
D'accord. Donc, je pourrais faire les deux. gzopen () pourrait convertir de l'UTF-8 en UTF-16 et appeler _wopen lors de la compilation de Windows. Et il pourrait également y avoir un _wgzopen () qui utilise UTF-16 pour une entrée (pour les deux arguments?). Je ne reçois pas tout le "délégué aux fonctions de sensibilisation des paramètres régionaux existants". Cela signifie-t-il que la routine qui convertit de l'UTF-8 en UTF-16 n'est pas "au courant"? Au fait, quelle est cette routine?
@Markadler: Cette routine est MultiByteTowidechar () Code> ou
iconv () code>.
Voici une implémentation de l'option N ° 2 de Appleman. Le code a été testé.
FILE* _wfopen(const wchar_t* filename, const wchar_t* mode);
Testé cela avec la compilation Visual Studio 2010, dans le débogage, vous obtenez une exception lorsque l'application est sur le point de se terminer. Cela vient probablement parce que le fichier a été ouvert à l'aide de _wfopen, mais après cette poignée est fermée par _Close. Il est possible que vous puissiez obtenir une implémentation "sans danger" par DUP: la licence Fileno, puis fermez-la, mais j'ai joint ma propre implémentation de cette fonction ci-dessous.
Il y a une certaine bizarrerie lorsque cela est exécuté en application. L'application se termine bien, mais dans l'icône de la barre d'affaires, j'ai remarqué que certains bugs sont envoyés à Microsoft - c'est la première fois que je vois un rapport de bogue "silencieux". Rien n'est affiché pour mettre fin à l'utilisateur.
Débogué en VS2012 et après la fin de l'application se termine, une exception est affichée - vous essayez de mettre fin à l'application, mais le débogueur se bloque pendant une demi-minute. Également vs doit être redémarré après ce bogue.
La prochaine version de ZLIB comprendra cette fonction où Il fonctionne exactement comme J'ai volontairement ne pas dupliquer le deuxième argument de _win32 code> est #defined: p>
gzfile gzopen_w (const wchar_t * chemin, mode char *); code> p>
gzopen () code>, sauf qu'il utilise
_wopen () code> au lieu de
ouvert () code>. p>.
_wfopen () code> et, par conséquent, je ne l'ai pas appelé
_wgzopen () code> pour éviter toute confusion possible avec les arguments de cette fonction . D'où le nom
gzopen_w () code>. Qui évite également l'utilisation de l'espace de nom réservé à C. P>
Meilleur type de réponse. Vous demandez comment le faire et l'auteur de la bibliothèque est livré avec une nouvelle fonctionnalité.
@ Erkinalpgüney Je ne suis pas d'accord, une meilleure option consisterait à utiliser le suivi de la question. BTW: cette la version suivante i> était 1.2.7 (2 mai 2012) b> (voir Premier commis sur ce , il n'y a pas d'entrée correspondante dans le suivi de la question)
Voici ma propre version de Unicode Helper Fonction, testée légèrement mieux que la version ci-dessus.
Mark a ajouté une prise en charge des noms de fichiers de caractères larges sur Windows aux versions récentes de ZLIB.
Je suis d'accord. Mais si vous avez déjà une bibliothèque de ZLIB et que vous ne voulez pas vous soucier de la ré-intégration de la nouvelle bibliothèque (compatibilité à l'envers, de nouvelles fonctionnalités, etc.) - Ensuite, il est plus facile d'envelopper existant.
Vous devez passer o_binary code> à
_wopen code> dans tous les cas, non seulement si les données non compressées sont binaires, sinon elle corrompre toutes les 0x10 dans la sortie comprimée!
Pas sûr, mais je m'attendrais à ce que cela accepte UTF8, de sorte que vous puissiez convertir votre UTF16 en UTF8 et transmettre le résultat comme
char * code>.
Avez-vous essayé d'utiliser wcstombs ou iconv ?
@Appleman: sur Windows WCSTOMBS sera au moins par défaut, convertira la chaîne à Windows-1252. Les caractères qui ne peuvent pas être représentés comme Windows-1252 seront remplacés par divers caractères de substitution. Si cela se produit, la chaîne convertie ne peut pas être utilisée comme chemin de fichier.
C'est ce que le client SVN de la console sous Windows fait, apparemment. Et cela rend le travail avec des noms de fichiers unicodes vraiment douloureux;)
Difficile de voir ce problème, c'est un problème pour le gars qui créé i> le fichier gzip. Les noms de fichiers sont codés dans ISO 8859-1. Ou quelle que soit l'application utilisée qui a créé le fichier, un problème courant.
@Hans Passant: J'écris une bibliothèque dont l'interface prend un chemin de fichier en tant que Soost :: FileSystem :: Path et dont la mise en œuvre peut lire le fichier à l'aide de la bibliothèque ZLIB. Ensuite, c'est un problème.
Donc, convertissez simplement la corde de large en étroit. ICU par exemple.
@Hans Passant: étroit avec ce qui codant? Le codage par défaut sur Windows pour chaînes étroites est Windows-1252 et qui ne fonctionnera pas. Il ne peut pas gérer la plupart des points de code ci-dessus 0xFF.
Citation: "Les noms de fichiers sont codés dans ISO 8859-1".
@Hans Passant: Je lis ça, mais je n'ai pas compris ce que tu veux dire. Je peux créer des fichiers sur mon ordinateur Windows avec des noms tels que "黒 .txt". Et je peux ouvrir ce fichier en passant son nom (en tant que chaîne large codée UTF-16) à _wfopen (...)
@Hans Passant: Comment ifil irait "黒 死 .txt" avec ISO 8859-1? De toute évidence, il me manque un peu d'informations. S'il vous plaît éclairer moi.
Encore une fois, c'est un problème pour le gars qui crée i> le gzip. Vous pouvez facilement supposer que GZIP n'est pas un format très populaire en Asie de l'Est.
Le problème est que certaines bibliothèques entre votre code et le système d'exploitation ont besoin d'un
char * code>. (au moins c'est mon problème et pourquoi je suis ici aujourd'hui). Donc, il doit y avoir un moyen de faire
wchar * code> → → [Lib Space]
char * code> →
fopen code> → [espace OS]
_wfopen < / code>, avec la finale _wfopen ayant une reconstruction de la chaîne d'origine. La question est donc de savoir quelle est la fonction inverse du
toutf16 code>? est-ce
wcstombs code>? Pendant la chaîne entre My-Code et My Space, il n'est pas nécessaire de pouvoir interpréter la chaîne sous forme de glyphes, des caractères non codables peuvent être conservés comme MBS et reconstruit par ToutF16.