使用带有无效字符的 Net::FTP gettextfile (ASCII-8BIT vs UTF-8)

Posted

技术标签:

【中文标题】使用带有无效字符的 Net::FTP gettextfile (ASCII-8BIT vs UTF-8)【英文标题】:Using Net::FTP gettextfile with invalid characters (ASCII-8BIT vs UTF-8) 【发布时间】:2014-07-02 22:30:05 【问题描述】:

我有一个通过 FTP 从大型机获取平面文件的进程。这通常可以正常工作,但文件时不时会包含重音字符。如果我尝试获取包含重音的文件,整个过程将失败并出现以下错误:Encoding::UndefinedConversionError: "\x88" from ASCII-8BIT to UTF-8

这是使用Net::FTPgettextfile 方法。许多人建议简单地切换到getbinaryfile - 这样做可以让我下载文件,但生成的文件是我无法再解析的东西(说它是UTF-8,但内容没有意义)。

有没有什么方法可以简单地获取文件并将其保存为 ASCII 而无需让 rails 自动将输出转换为 UTF-8?这是我的代码:

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

【问题讨论】:

您缺少违规文本的示例。了解文件的前两个字节是什么以及文件的小十六进制转储也将有所帮助。 “寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题是没有用的给其他读者。见:How to create a Minimal, Complete, and Verifiable example。” 你的意思是带重音字符的文件不是UTF-8编码的吗? 【参考方案1】:

如果我没记错的话,FTP-dom 中的文本文件是 ASCII-7bit 并且不能包含具有高位设置的字符,AKA ASCII-8BIT。重音字符,即使是扩展的 ASCII 或 8BIT 或任何我们想要调用的任何高于 0x7F 的字符,都需要以二进制模式传输。

来自the 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).

所以是的,你应该改用getbinaryfile

两者之间的主要实际区别是二进制模式不会进行行尾翻译。如果源系统基于 ECDIC 或替代字长,gettextfile 将即时将文件转换为 ASCII。遇到不在预期编码中的字符很容易引发您所看到的问题。

如果文件在使用getbinaryfile 传输后没有意义,则它可能在主机上的替代代码集中,而不是 UTF8。您必须弄清楚它在该系统上的代码集,并在下载后使用适当的编码设置打开文件。您可以在 *nix 系统上使用 file 命令对文件的编码进行有根据的猜测,但这不是一个详尽的测试,并且可能会产生误导。因为文件来自大型机,它可能使用不同的字长,如 UTF-16BE、UTF-32LE 或以 EBCDIC 编码。这就是处理备用操作系统和硬件变得非常烦人的地方。

没有文本示例、文件的前两个字节以及十六进制转储中的文本样本,很难为您提供帮助。

毕竟,使用cURL 或Curb gem 来检索文件可能更容易。 cURL 非常灵活且功能强大,可能会为您提供所需的工具。

【讨论】:

以上是关于使用带有无效字符的 Net::FTP gettextfile (ASCII-8BIT vs UTF-8)的主要内容,如果未能解决你的问题,请参考以下文章

带有法语特殊字符 (è d') 的无效 XPath

如何将带有无效字符(重音)的 Pandas 数据框与数组匹配? [复制]

HttpRequestMessage.Content 带有无效和不可读的字符

带有 Spring Data JPA 的 Spring Boot 为 Oracle 数据库上的 findOne(...) 提供了无效字符问题

SQL 查询字符串在 SQL Server Management Studio 中有效,但在带有 SQLCommand.ExecuteReader 的 VB.net 中无效

带有消息“SQLSTATE [22007]”的未捕获异常“PDOException”:日期时间格式无效:1366 字符串值不正确