Pregunta

Estoy consumiendo una fuente de datos que recientemente agregó un encabezado de lista de materiales Unicode (U+FEFF) y mi tarea de rake ahora está arruinada.

Puedo omitir los primeros 3 bytes con file.gets[3..-1] pero, ¿existe una forma más elegante de leer archivos en Ruby que pueda manejar esto correctamente, ya sea que haya una lista de materiales presente o no?

¿Fue útil?

Solución

con Ruby 1.9.2 se puede utilizar el modo de 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
}

o

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

o

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

No importa, si la lista de materiales está disponible en el archivo o no.


También puede utilizar la opción de codificación con otros comandos:

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

(Se obtiene una matriz con todas las líneas).

O con CSV:

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

Otros consejos

No me saltaría ciegamente los primeros tres bytes;¿Qué pasa si el productor? se detiene ¿Agregar la lista de materiales nuevamente?Lo que deberías hacer es examinar los primeros bytes, y si son 0xEF 0xBB 0xBF, ignórelos.Esa es la forma que adopta el carácter BOM (U+FEFF) en UTF-8;Prefiero ocuparme de ello antes de intentar decodificar la transmisión porque el manejo de la lista de materiales es muy inconsistente de un lenguaje/herramienta/marco a otro.

De hecho, así es como eres supuesto para tratar con una lista de materiales.Si un archivo se entregó como UTF-16, debe examinar los primeros dos bytes antes de comenzar a decodificarlo para saber si leerlo como big-endian o little-endian.Por supuesto, la lista de materiales UTF-8 no tiene nada que ver con el orden de los bytes, solo está ahí para informarle que la codificación es UTF-8, en caso de que aún no lo sepa.

Me no la "confianza" algún archivo que va a codificarse como UTF-8 cuando está presente una lista de materiales de 0xEF 0xBB 0xBF, es posible que no vaya. Por lo general, cuando se detecta la BOM UTF-8, lo que realmente debe ser un archivo codificado en UTF-8, por supuesto. Pero, si por ejemplo alguien que acaba de añadir la lista de materiales UTF-8 a un archivo ISO, usted no puede codificar tal archivo tan malo si existen bytes en los mismos que están por encima de 0x0F. Usted puede confiar en el archivo si sólo tiene los bytes hasta 0x0F en el interior, ya que en este caso se trata de un archivo UTF-8 compatible con ASCII y, al mismo tiempo, es un archivo válido UTF-8.

Si no son sólo los bytes <= 0x0F dentro del archivo (después de la lista de materiales), para asegurarse de que esté correctamente codificación UTF-8 que tendrá que comprobar si hay secuencias válidas y - aún cuando todas las secuencias son válidas - cheque también si cada punto de código de una secuencia utiliza la secuencia más corta posible y comprobar también si no hay punto de código que coincide con una alta o baja sustituto. También comprobar si los bytes máximos de una secuencia no es más de 4 y el más alto punto de código es 0x10ffff. Los límites más altos codepoint también bits de carga útil del startbyte a ser no mayor de 0x4 y la carga útil del primer byte después de no más de 0xF. Si todas las comprobaciones mencionadas pasan exitosamente, su BOM UTF-8 dice la verdad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top