【问题标题】:ArgumentError: invalid byte sequence in UTF-8 when creating CSV from TempFileArgumentError:从 TempFile 创建 CSV 时 UTF-8 中的字节序列无效
【发布时间】:2016-06-28 14:10:05
【问题描述】:

我有以下两行代码,它们从 params 获取上传的 CSV 文件并返回 Contact 对象的哈希值。当我输入带有 UTF-8 编码的 CSV 时,代码工作正常。但是,如果我尝试使用另一种编码方式上传 CSV,它就会中断。如何调整代码以检测上传文件的编码并转换为 UTF-8?

CSV::Converters[:blank_to_nil] = lambda { |field| field && field.empty? ? nil : field }
csv = CSV.new(params[:file].tempfile.open, headers: true, header_converters: :symbol, converters: [:all, :blank_to_nil]).to_a.map {|row| row.to_hash }

这个问题不是重复的!我在这里看到很多其他问题都围绕着相同的编码问题,但这些问题的具体情况与我的情况不同。具体来说,我需要一种方法来转换从我的params 哈希生成的TempFile 的编码。我见过的其他解决方案包括编码StringFile 对象,以及将编码选项传递给CSV.parseCSV.open。我已经尝试过这些解决方案,但没有成功。

我尝试将编码选项传递给CSV.new,如下所示:

csv = CSV.new(params[:file].tempfile.open, encoding: 'iso-8859-1:utf-8', headers: true, header_converters: :symbol, converters: [:all, :blank_to_nil]).to_a.map {|row| row.to_hash }

我也试过这个:

csv = CSV.new(params[:file].tempfile.open, encoding: 'iso-8859-1:utf-8', headers: true, header_converters: :symbol, converters: [:all, :blank_to_nil]).to_a.map {|row| row.to_hash }

我也尝试过调整我的转换器,如下所示:

CSV::Converters[:blank_to_nil] = lambda { |field| field && field.empty? ? nil : field.encode('utf-8') }

我在这里寻找一种不需要用户将其 CSV 转换为正确编码的程序化解决方案。

【问题讨论】:

  • 有一些用于检测字符编码的宝石很容易用谷歌搜索。

标签: ruby-on-rails ruby csv encoding utf-8


【解决方案1】:

我也不得不处理这个问题,这就是我最终解决它的方法。

  CSV.open(new_csv_file, 'w') do |csv_object|
    lines = File.open(uploaded_file).read
    lines.each_line do |line|
      csv_object << line.encode!("utf-8", "utf-8", invalid: :replace, undef: :replace, replace: '').parse_csv
    end
  end
  CSV.new(File.read(new_csv_file))

基本上遍历每一行,对其进行清理并将其推入一个新的 CSV 文件中。 希望能引导您和其他人朝着正确的方向前进。

【讨论】:

  • 我无法让您的代码适应我的。第 1 行的 new_csv_file 定义在哪里?
  • new_csv_file 将是一个临时文件。你可以这样定义它:new_csv_file = Tempfile.new("some_csv_file")
  • 您是否得到了这个工作或者您仍然有问题?如果它确实解决了您的问题,请投票。
  • 它适用于我在代码编辑器中创建的示例 CSV 文件之一,但不适用于我从 Excel 导出的另一个文件。我仍然没有让我的 CSV 导入方法正常工作,但它一直在我的议程上。希望下周能更深入地讨论它。
  • 酷,感谢您的投票。您可能想尝试从 Excel 导出为 csv(Windows 逗号分隔)。干杯。
【解决方案2】:

您可以使用filemagic 来检测文件的编码,尽管它不是 100% 准确的。它基于系统的file 命令工具,所以我不确定它是否适用于windows。

【讨论】:

    猜你喜欢
    • 2015-07-04
    • 2016-07-05
    • 2013-08-20
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 2017-03-31
    • 2012-12-11
    • 2023-04-03
    相关资源
    最近更新 更多