Comment éviter de trébucher sur UTF-8 BOM lors de la lecture de fichiers
je suis en train de consommer un flux de données qui a récemment ajouté un en-tête Unicode BOM (U+FEFF), et ma tâche rake est maintenant fichue par elle.
je peux sauter les 3 premiers octets avec file.gets[3..-1]
mais y a-t-il une façon plus élégante de lire les fichiers dans Ruby qui peut gérer cela correctement, si un BOM est présent ou non?
3 réponses
avec ruby 1.9.2 vous 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')
cela n'a pas d'importance, que le BOM soit 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 }
}
Je ne sauterais pas aveuglément les trois premiers octets; et si le producteur arrête ajoutant le BOM à nouveau? Ce que vous devez faire est examiner les premiers octets, et s'ils sont 0xEF 0xBB 0xBF, ignorez-les. C'est la forme que prend le caractère BOM (U+FEFF) en UTF-8; je préfère le traiter avant d'essayer de décoder le flux parce que la manipulation de BOM est tellement incohérente d'un langage/outil/framework à l'autre.
In en fait, c'est comme ça que tu es supposé pour gérer un BOM. Si un fichier a été servi comme UTF-16, Vous devez examiner les deux premiers octets avant de commencer le décodage afin de savoir si vous devez le lire comme big-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 l'encodage est UTF-8, au cas où vous ne le saviez pas déjà.
Je ne ferais pas" confiance " à un fichier pour être encodé en UTF-8 quand un BOM de 0xEF 0xBB 0xBF est présent, vous pourriez échouer. Habituellement, lors de la détection de la BOM UTF-8, Il devrait vraiment être un fichier encodé UTF-8 Bien sûr. Mais, si par exemple quelqu'un vient d'ajouter le BOM UTF-8 à un fichier ISO, vous ne réussirez pas à encoder un tel fichier si mal s'il y a des octets qui sont au-dessus de 0x0F. Vous pouvez faire confiance au fichier si vous avez seulement des octets jusqu'à 0x0F à l'intérieur, parce que dans ce cas, c'est un fichier ascii compatible UTF-8 et au en même temps, il s'agit d'un fichier UTF-8 valide.
S'il n'y a pas seulement des octets <= 0x0F dans le fichier (après le BOM), pour être sûr QU'il est correctement encodé UTF-8 vous devrez vérifier les séquences valides et - même lorsque toutes les séquences sont valides - vérifier aussi si chaque point codé d'une séquence utilise la séquence la plus courte possible et vérifier aussi s'il n'y a pas de point codé qui correspond à un HIGH - ou low-Merchant. Vérifiez également si le nombre maximum d'octets d'une séquence n'est pas supérieur à 4 et le nombre le plus élevé codepoint est 0x10ff. Les limites de codepoint les plus élevées aussi les bits de charge utile du startbyte ne doivent pas être supérieurs à 0x4 et le premier octet suivant la charge utile ne doit pas être supérieur à 0xF. Si toutes les vérifications mentionnées passent avec succès, votre BOM UTF-8 dit la vérité.