ruby on rails - Usando Net:: FTP gettextfile con caracteres no válidos(ASCII-8BIT vs UTF-8)
ruby-on-rails encoding (1)
Tengo un proceso que obtiene un archivo plano de un mainframe a través de FTP. Esto generalmente funciona bien, pero de vez en cuando el archivo contendrá algo con carácter de acento. Si trato de obtener un archivo que contenga un acento, todo el proceso falla con el siguiente error: Encoding::UndefinedConversionError: "/x88" from ASCII-8BIT to UTF-8
Eso es usando el método gettextfile
Net::FTP
. Mucha gente sugiere simplemente cambiar a getbinaryfile
; al hacerlo, me permitirá descargar el archivo, pero el archivo resultante es algo que ya no puedo analizar (dice que está en UTF-8, pero el contenido no tiene sentido).
¿Hay alguna manera de simplemente recuperar y guardar el archivo como ASCII sin que los rieles conviertan automáticamente la salida a UTF-8? Aquí está mi código:
Net::FTP.open(config[''host'']) do |ftp|
Rails.logger.info("FTP Connection established")
ftp.login(config[''user''], config[''password''])
Rails.logger.info("Login Successful")
ftp.gettextfile("''#{config[''es_in'']}''", "data/es-in.#{Time.now.utc.strftime("%Y%m%d-%H%M%S")}")
ftp.gettextfile("''#{config[''ca_in'']}''", "data/ca-in.#{Time.now.utc.strftime("%Y%m%d-%H%M%S")}")
Rails.logger.info("Download(s) completed, terminating connection.")
end
Si recuerdo bien, los archivos de texto en FTP-dom son ASCII-7bit y no pueden contener caracteres con el conjunto de bits superior, AKA ASCII-8BIT. Los caracteres acentuados, incluso en ASCII extendido o 8BIT o lo que queramos llamar, por encima de 0x7F, deben transferirse en modo binario.
Desde el FTP RFC :
ASCII
The ASCII character set is as defined in the ARPA-Internet
Protocol Handbook. In FTP, ASCII characters are defined to be
the lower half of an eight-bit code set (i.e., the most
significant bit is zero).
Entonces sí, probablemente deberías usar getbinaryfile
en getbinaryfile
lugar.
La principal diferencia práctica entre los dos es que el modo binario no hará las traducciones de final de línea. Si el sistema fuente está basado en ECDIC o en un tamaño de palabra alternativo, gettextfile
traducirá el archivo sobre la marcha en ASCII. Encontrar caracteres que no están en la codificación esperada podría desencadenar fácilmente el tipo de problema que estás viendo.
Si el archivo no tiene sentido después de la transferencia utilizando getbinaryfile
, podría estar en un conjunto de códigos alternativo que UTF8 en el mainframe. Tendrá que averiguar en qué conjunto de códigos está en ese sistema y abrir el archivo con la configuración de codificación adecuada después de la descarga. Puede usar el comando de file
en los sistemas * nix para hacer una conjetura sobre la codificación de un archivo, pero no es una prueba exhaustiva y puede inducir a error. Como el archivo proviene de un mainframe, podría estar usando un tamaño de palabra diferente como UTF-16BE, UTF-32LE o estar codificado en EBCDIC. Aquí es donde lidiar con sistemas operativos y hardware alternativos se vuelve realmente molesto.
Sin ejemplos del texto, los primeros dos bytes del archivo y un muestreo del texto en un volcado hexadecimal, es difícil ayudarte.
Y, después de todo eso, podría ser más fácil usar cURL , o la gema Curb para recuperar el archivo. cURL es muy flexible y potente, y podría proporcionarle las herramientas que necesita.