Question

Je consomme un flux de données qui a récemment ajouté un en-tête de nomenclature Unicode (U + FEFF), et ma tâche de râteau est maintenant sali par elle.

Je peux sauter les 3 premiers octets avec file.gets[3..-1], mais est-il une façon plus élégante de lire les fichiers en Ruby qui peut gérer cela correctement, si une nomenclature est présent ou non?

Était-ce utile?

La solution

Avec rubis vous 1.9.2 pouvez utiliser le mode r:bom|utf-8

text_without_bom = nil #define the variable outside the block to keep the data
File.open('file.txt', "r:bom|utf-8"){|file|
  text_without_bom = file.read
}

ou

text_without_bom = File.read('file.txt', encoding: 'bom|utf-8')

ou

text_without_bom = File.read('file.txt', mode: 'r:bom|utf-8')

Peu importe, si la nomenclature est disponible dans le fichier ou non.


Vous pouvez également utiliser l'option d'encodage avec d'autres commandes:

text_without_bom = File.readlines(@filename, "r:utf-8")

(Vous obtenez un tableau avec toutes les lignes).

Ou avec CSV:

require 'csv'
CSV.open(@filename, 'r:bom|utf-8'){|csv|
  csv.each{ |row| p row }
}

Autres conseils

Je ne sauter aveuglément les trois premiers octets; si le producteur arrête ajouter la nomenclature à nouveau? Ce que vous devez faire est de examiner les premiers octets, et si elles sont 0xEF 0xBB 0xBF, ignorez-les. C'est la forme prend en UTF-8 le caractère BOM (U + FEFF); Je préfère traiter avant d'essayer de décoder le flux, car la manipulation de nomenclature est donc incompatible d'une langue / outil / cadre à l'autre.

En fait, c'est la façon dont vous êtes supposé pour faire face à une nomenclature. Si un fichier a été servi en UTF-16, vous devez examiner les deux premiers octets avant de commencer à décoder afin de savoir si le lire aussi grand-endian ou little-endian. Bien sûr, le BOM UTF-8 n'a rien à voir avec l'ordre des octets, il est juste là pour vous faire savoir que le codage est UTF-8, au cas où vous ne saviez pas déjà.

Je ne serais pas « confiance » certains fichiers à coder en UTF-8 quand une nomenclature de 0xEF 0xBB 0xBF est présent, vous pouvez échouer. En général, lors de la détection de la BOM UTF-8, il devrait vraiment être un fichier codé UTF-8 bien sûr. Mais, si par exemple quelqu'un vient d'ajouter la nomenclature dans un fichier ISO UTF-8, vous souhaitez ne parvenez pas à encoder ce fichier si mauvais s'il y a des octets dans ce qui sont au-dessus 0x0F. Vous pouvez faire confiance au fichier si vous avez octets seulement jusqu'à 0x0F l'intérieur, parce que dans ce cas, il est un fichier ASCII compatible UTF-8 et en même temps, il est un fichier UTF-8 valide.

S'il n'y a pas seulement les octets <= 0x0F dans le fichier (après la nomenclature), pour être sûr qu'il est correctement codage UTF-8, vous devrez vérifier les séquences valides et - même lorsque toutes les séquences sont valides - vérification même si chaque point de code à partir d'une séquence utilise la plus courte séquence possible et aussi vérifier s'il n'y a pas codepoint qui correspond à une haute ou basse de substitution. Vérifiez également si les octets maximum d'une séquence ne dépasse pas 4 et le plus haut point de code est 0x10FFFF. Les plus hautes limites de codepoint aussi les bits de charge utile du startbyte ne pas être plus élevé que 0x4 et la première charge utile de l'octet suivant ne dépasse pas 0xF. Si tous les contrôles mentionnés passent avec succès, votre BOM UTF-8 dit la vérité.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top