J'ai écrit une application (un examen de test psychologique) dans Delphi (7) qui crée un fichier texte standard - c'est-à-dire que le fichier est de type ANSI. p>
Quelqu'un a porté le programme à exécuter sur Internet, en utilisant probablement Java et le fichier texte résultant est de type UTF-8. p>
Le programme qui lit ces fichiers de résultats devra lire les deux fichiers créés par Delphi et les fichiers créés via Internet. p>
tandis que je peux convertir le texte UTF-8 en ANSI (à l'aide de la fonction ruse nommée UTF8TOANSI), comment puis-je dire à l'avance quel type de fichier que j'ai? p>
Voir comme je "posséder" le format de fichier, je suppose que le moyen le plus simple de gérer cela serait de placer un marqueur dans le fichier à une position connue qui me dira la source du programme (Delphi / Internet), Mais cela semble tricher. p>
Merci d'avance. P>
5 Réponses :
Si le fichier UTF commence par la marque OTF-8 octet-ordre (BOM), c'est facile:
function UTF8FileBOM(const FileName: string): boolean; var txt: file; bytes: array[0..2] of byte; amt: integer; begin FileMode := fmOpenRead; AssignFile(txt, FileName); Reset(txt, 1); try BlockRead(txt, bytes, 3, amt); result := (amt=3) and (bytes[0] = $EF) and (bytes[1] = $BB) and (bytes[2] = $BF); finally CloseFile(txt); end; end;
Que se passe-t-il si la nomenclature a une interprétation valide dans le jeu de caractères "ANSI"?
Trouver une nomenclature sur les données UTF-8 est assez rare, car l'UTF-8 est endianness-agnostique et donc Ne nécessite pas de nomination pour déterminer l'ordre d'octet .
@larsmans "ANSI" est généralement juste un alias pour "Windows-1252". Donc oui, la naissance a une interprétation valide dans "ANSI" ...
@DKARP: Oui, et nous savons tous comment la chômage semble interprétée en 1252.
@dkarp vos points sont tous corrects mais semblent ne pas pertinents pour cette question
@Andreas oh, oui. Mais toujours, -1 à cette réponse. Vous vraiment i> ne peut pas compter sur une nomenclature dans les données UTF-8. Une réponse bonne i> essayerait de tester si les données sont valides UF-8 ...
@David: Cette réponse dit essentiellement "Cherchez la naissance." (Et c'est tout ce que le code fait.) Sauf que 9 fois sur 10, un fichier UTF-8 n'a pas de naissance car il ne a besoin i> un bom ...
@DKARP: Eh bien, j'ai écrit " si b> Le fichier UTF commence par la marque UTF-8 octet-commander (BOM), c'est facile:". Ainsi, j'ai donné une condition suffisante (bien), mais pas nécessaire. (J'ai même fini ma réponse avec "sinon, c'est beaucoup plus difficile.".) J'étais inconnu à une règle disant qu'une réponse à ce jour devait être complète pour être utile ...
@DKARP Le mot ANSI en tant que Microsoft signifie le héritage local CharSet et peut différer du système au système en fonction de la langue du système d'exploitation.
@Codeinchaos qui fait beaucoup plus de sens, en fait. Merci!
Je dois être vraiment épais, car je ne peux pas voir pourquoi quiconque même modérément sobre va descendre cela ...
@Andreas tandis que je n'aime pas compter sur Bom, je ne pense pas que cela mérite un bowvote. Mais il semble que quelqu'un ait descendu toutes les réponses à ce fil.
@Andreas Je suis l'un des 2 bowvotes et je pensais avoir expliqué pourquoi. 90 %% de temps, votre réponse n'est tout simplement pas utile, car les fichiers UTF-8 ont rarement rarement un bom. C'est une sorte de réponse "Comment reproduire MySQL utf8_unicode_ci code> en java?" En disant "Eh bien, si les deux chaînes sont vides, vous retournerez 0. Sinon, c'est beaucoup plus difficile." Oui c'est vrai. Mais pas utile.
J'accepte cette réponse car le fichier créé par la version Internet du programme a en effet un bom - ses trois premiers caractères sont EF BB BF. Je vais demander à la personne qui a créé la version Internet pour créer quelques fichiers supplémentaires afin que je puisse vérifier cela plus soigneusement. Merci à tous ceux qui ont participé.
+1, comme indiqué à Andreas, la réponse est correcte et que les conditions sont indiquées. Aucune raison de la descendre!
Il n'y a pas de moyen sûr de 100% de reconnaître le codage de l'ANSI (par exemple Windows-1250) à partir de l'encodage UTF-8. Là sont em> les fichiers ANSI qui ne peuvent pas em> être valides UTF-8, mais chaque fichier valide UF-8 valide peut aussi bien être un fichier ANSI différent. (Sans parler des données ASCII uniquement, qui sont em> ANSI et UTF-8 par définition, mais c'est purement un aspect théorique.) P>
Par exemple, la séquence C4 8D pourrait être le caractère "Č" dans UTF-8, ou cela pourrait être "Äť" dans Windows-1250. Les deux sont possibles et correct. Cependant, par exemple 8d 9a peut être "ťŠ" dans Windows-1250, mais ce n'est pas une chaîne UTF-8 valide. P>
Vous devez recourir à une sorte de heuristique, par exemple p>
Voir aussi La méthode utilisée par le bloc-notes . P >
+1, bien que j'exclureais UTF-16LE et UTF-16BE en fonction de leurs marques d'ordre d'octets et éventuellement sur des octets d'alternance zéro / non zéro, avant de décider de l'UTF-8 ...
@Marjan - Eh bien, la question spécifique ici portait sur la distinction des ANSI de UTF-8; UTF-16 n'est pas prévu du tout. Mais dans le cas générique, vous avez raison, il y a beaucoup plus de questions à poser. (Et la méthode istextUncode mentionnée dans le lien aideraient avec cet étui UTF-16.)
Lorsque vous lisez d'abord, essayez d'analyser le fichier comme UTF-8. S'il n'est pas valide UTF-8 interpréter le fichier comme codage hérité (ANSI). Cela fonctionnera sur la plupart des fichiers, car il est très peu probable qu'un fichier codé legacy codé soit valide UTF-8. P>
Qu'est-ce que Windows appelle ANSI est un système de caractères dépendants du système. Et le texte ne fonctionnera pas correctement sur une fenêtre russe, ou asiatique ou ... Windows. P>
Bien que le VCL ne prenne pas en charge Unicode dans Delphi 7, vous devez toujours travailler à l'intérieur de l'Unicode et ne convertit que vers ANSI pour l'afficher. J'ai localisé l'un de mes programmes de coréens et russe, et c'était la seule façon dont je l'ai eu de travailler sans gros problèmes. Vous ne pouviez toujours afficher que la localisation coréenne sur un système défini sur coréen, mais au moins les fichiers texte pourraient être modifiés sur n'importe quel système. P>
Si nous Summerize strong>, alors: Autres informations Les personnes peuvent être trouvées intéressantes: p> https://groups.google .com / Forum /? LNK = ST & Q = Delphi + Win32 + Fonctions + To + Détecter + Le + Encodage ++ est + In + Utilisation & RNUM = 1 & HL = PT-BR & PLI = 1 #! Sujet / Borland.Public.delphi.Internationalisation. win32 / _llolx25oa p> essais maintenant cette fonction ... p> dans mon humble avis Seulement comment commencer à faire ce chèque correctement Pour vérifier OS Charset en premier lieu car à la fin, presque dans tous les cas, des références au système d'exploitation. Aucun moyen de le scaper quand même ... p> remarques: em> p>
Si vous combinez la réponse marquée et celle-ci en une seule procédure, cela serait assez précis et rapide.
//if is possible to decoded,then it is UTF8 function isFileUTF8(const Tex : AnsiString): boolean; begin result := (Tex <> '') and (UTF8Decode(Tex) <> ''); end;
Qu'est-ce que isfileutf8 ('abcde') retourner?
Mettre un marqueur indiquant que le codage ne triche pas, il est assez standard (XML le fait). La question est plutôt si la conversion de vos anciens fichiers est un problème.
Si vous possédez le fichier, mettez simplement un bom dans et tout est bon
Faites votre propre format Utilisez UTF-8 pour les nouveaux fichiers également. L'utilisation d'une locale dépendante dépendante conduit à de nombreuses horreurs.
Un bom peut gâcher des applications, je n'en ajouterais jamais un à un fichier codé UTF-8 - à moins que je ne sois obligé de :)
Un fichier texte peut être à la fois ANSI et UTF8 s'il colle sur le sous-ensemble ASCII
Il semble que le fichier Internet fait I> a un bom, donc je vais vérifier pour cela d'abord avant d'utiliser la fonction UTF8TOANSI. Merci à tous.