2009-06-02 3 views
2

J'ai besoin de convertir des fichiers en UTF-8 parce qu'ils sont dans un autre délivrés le site UTF-8 et le contenu semble un peu fugly parfois.La conversion par lots de codage de fichier inconnu en UTF-8

Je peux soit faire maintenant ou je peux le faire comme ils sont lus (par PHP, juste en utilisant fopen, rien d'extraordinaire). Toutes les suggestions sont les bienvenues

+0

Etes-vous sûr que c'est juste un mauvais encodage ou que quelques glyphes manquent? – Gumbo

+0

Assez sûr qu'il a été écrit dans un jeu de caractères non-UTF-8. Plusieurs fichiers montrent le même résultat pour les mêmes caractères douteux (e-acute, etc). – Oli

Répondre

7

Je ne J'ai une solution claire pour PHP, mais pour Python, j'ai personnellement utilisé Universal Encoding Detector library qui fait un très bon travail pour deviner quel est l'encodage du fichier. Pour commencer, voici un script Python que j'avais utilisé pour faire la conversion (l'objectif initial était de convertir une base de code japonaise à partir d'un mélange d'UTF-16 et de Shift-JIS, que je fait une supposition par défaut si chardet n'est pas sûr de détecter l'encodage):

import sys 
import codecs 
import chardet 
from chardet.universaldetector import UniversalDetector 

""" Detects encoding 

Returns chardet result""" 
def DetectEncoding(fileHdl): 
detector = UniversalDetector() 
for line in fileHdl: 
    detector.feed(line) 
    if detector.done: break 
detector.close() 
return detector.result 


""" Reencode file to UTF-8 
""" 
def ReencodeFileToUtf8(fileName, encoding): 
    #TODO: This is dangerous ^^||, would need a backup option :) 
    #NOTE: Use 'replace' option which tolerates errorneous characters 
    data = codecs.open(fileName, 'rb', encoding, 'replace').read() 
    open(fileName, 'wb').write(data.encode('utf-8', 'replace')) 

""" Main function 
""" 
if __name__=='__main__': 
    # Check for arguments first 
    if len(sys.argv) <> 2: 
    sys.exit("Invalid arguments supplied") 

    fileName = sys.argv[1] 
    try: 
     # Open file and detect encoding 
     fileHdl = open(fileName, 'rb') 
     encResult = DetectEncoding(fileHdl) 
     fileHdl.close() 

     # Was it an empty file? 
     if encResult['confidence'] == 0 and encResult['encoding'] == None: 
      sys.exit("Possible empty file") 

     # Only attempt to reencode file if we are confident about the 
     # encoding and if it's not UTF-8 
     encoding = encResult['encoding'].lower() 
     if encResult['confidence'] >= 0.7: 
      if encoding != 'utf-8': 
       ReencodeFileToUtf8(fileName, encoding) 
     else: 
      # TODO: Probably you could make a default guess and try to encode, or 
      #  just simply make it fail 

     except IOError: 
      sys.exit('An IOError occured') 
+0

Merci. J'ai écrit un petit script pour exécuter en arrière-plan basé sur cela et conserver les fichiers (que les sources PHP) en UTF-8 – Oli

+1

Un heads-up, le lien ci-dessus pour la bibliothèque Universal Encoding Detector est 410 Gone. Voici une URL de travail: http://pypi.python.org/pypi/chardet – jeffbyrnes

+0

@jeffbyrnes Merci pour le heads-up, corrigé le lien ci-dessus;) –

3

Le faire qu'une seule fois améliorerait les performances et réduire les risques d'erreurs futures, mais si vous ne connaissez pas l'encodage, vous ne pouvez pas faire une conversion correcte du tout.

2

Ma première tentative de ce serait:

  1. Si elle est syntaxiquement valide UTF-8, supposons qu'il est UTF-8.
  2. S'il y a des octets seulement correspondant à des caractères valides dans la norme ISO 8859-1 (Latin-1), supposer que.
  3. Sinon, échouez.
1

Est-ce qu'un fichier contient des données de différentes pages de codes?

Si oui, vous ne pouvez pas effectuer la conversion par lots. Vous devez connaître chaque codepage de chaque sous-chaîne de votre fichier.

Si aucun il est possible de convertir par lots un fichier à la fois, mais en supposant que vous savez ce que codepage ce fichier a. Nous sommes donc plus ou moins dans la même situation que ci-dessus, nous venons de déplacer l'abstraction de la portée de la sous-chaîne à la portée du fichier.

Donc, la question que vous devez vous poser est. Avez-vous des informations sur la page de code à laquelle certaines données appartiennent? Si ce n'est pas le cas, il aura toujours l'air fugace.

Vous pouvez toujours faire une analyse de vos données et devinez codepage, et bien que cela puisse en faire un peu moins fuglier, vous êtes devinant encore, et donc il sera toujours fugly :)

Questions connexes