2011-08-16 21 views
9

Me gustaría saber cómo puedo cambiar la codificación de mi archivo CSV cuando lo importo y lo analizo. Tengo este código:Cómo cambiar la codificación durante el análisis CSV en Rails

csv = CSV.parse(output, :headers => true, :col_sep => ";") 
csv.each do |row| 
    row = row.to_hash.with_indifferent_access 
    insert_data_method(row) 
end 

Cuando leí mi archivo, me sale este error:

Encoding::CompatibilityError in FileImportingController#load_file 
incompatible character encodings: ASCII-8BIT and UTF-8 

que leí sobre row.force_encoding('utf-8') pero no funciona:

NoMethodError in FileImportingController#load_file 
undefined method `force_encoding' for #<ActiveSupport::HashWithIndifferentAccess:0x2905ad0> 

Gracias.

+0

En lugar de convertirlo en una codificación diferente, lo haría Es posible agregar un paso de indirección y salida de archivos separados? Por ejemplo, un archivo de texto está codificado UTF-8 en algunas partes pero UTF-16LE en otras. Siempre que los encabezados sean idénticos, envíe un archivo a filename_utf8.txt y otro a filename_utf16le.txt. De esta forma, es posible no forzar la codificación. – Tyler

Respuesta

3

force_encoding está destinado a ejecutarse en una cadena, pero parece que lo está llamando en un hash. Se podría decir:

output.force_encoding('utf-8') 
csv = CSV.parse(output, :headers => true, :col_sep => ";") 
... 
+0

Acabo de intentarlo. Obtengo este error: 'ArgumentError en FileImportingController # load_file' ' secuencia de bytes no válida en UTF-8' – TW147

+0

intente ejecutar esto en su lugar: Iconv.conv ('utf-8 // IGNORE', 'utf-8', salida) –

+0

por desgracia, me sale ese error: 'codificación :: CompatibilityError en FileImportingController # load_file' ' incompatibles codificaciones de caracteres: ASCII-8BIT y UTF-8' – TW147

14

Debía leer los archivos CSV codificados en ISO-8859-1. haciendo las documentadas

CSV.foreach(filename, encoding:'iso-8859-1:utf-8', col_sep: ';', headers: true) do |row| 

lanzó la excepción

ArgumentError: invalid byte sequence in UTF-8 
    from csv.rb:2027:in '=~' 
    from csv.rb:2027:in 'init_separators' 
    from csv.rb:1570:in 'initialize' 
    from csv.rb:1335:in 'new' 
    from csv.rb:1335:in 'open' 
    from csv.rb:1201:in 'foreach' 

así que terminé de leer el archivo y su conversión a UTF-8 durante la lectura, a continuación, analizar la cadena:

CSV.parse(File.open(filename, 'r:iso-8859-1:utf-8'){|f| f.read}, col_sep: ';', headers: true, header_converters: :symbol) do |row| 
    pp row 
end 
0

Oye, escribí un pequeño blog post sobre lo que hice, pero es un poco más detallado de lo que ya se ha publicado. Por alguna razón, no pude lograr que esas soluciones funcionaran y esto fue así.

Lo esencial es que simplemente reemplace (o en mi caso elimine) los caracteres no válidos/indefinidos en mi archivo y luego vuelva a escribirlos. Utilicé este método para convertir los archivos:

def convert_to_utf8_encoding(original_file) 
    original_string = original_file.read 
    final_string = original_string.encode(invalid: :replace, undef: :replace, replace: '') #If you'd rather invalid characters be replaced with something else, do so here. 
    final_file = Tempfile.new('import') #No need to save a real File 
    final_file.write(final_string) 
    final_file.close #Don't forget me 
    final_file 
end 

Espero que esto ayude.

Editar: No codificación de destino se especifica aquí porque codifican asume que está a su codificación de codificación por defecto, que para la mayoría de aplicaciones Rails es UTF-8 (creo)

+0

Tomar la cadena y usar 'codificar' para eliminar los caracteres no válidos e indefinidos es lo que funcionó para mí. ¡Perfecto gracias! – zwickilton

Cuestiones relacionadas