ruby-on-rails - 有没有一个rails方法可以循环遍历上传文件的每一行? "each_line"是一个IO方法,但它不起作用

标签 ruby-on-rails file upload loops parameters

我正在尝试上传 csv 文件,解析它,然后为 S3 生成一个文件,或者只是传递给查看。我使用 file_field_tag 上传 csv。我认为 file_field_tag 传递的对象是 IO 的子类,并且具有所有 ruby​​ IO 方法,例如“each_line”。我可以在对象上调用“read”(IO 类的方法),但不能调用“each_line”...那么如何迭代 file_field_tag 上传的每一行?

我的 Controller 的创建方法为:

@csv_file = params[:csv_file]

我的显示 View 抛出无“each_line”方法错误:

<% @csv_file.each_line do |line| %>
<%= line %>
<% end %>

但是我可以使用

<%= @csv_file.read(100) %>

我真的很困惑 file_field_tag upload params[] 有什么方法...each_line, gets 不起作用...我似乎找不到我可以使用的列表。

编辑 我通过这样做解决了这个问题:

@csv_file = params[:csv_file].read.to_s

然后迭代:

<% @sp_file.each_line do |line| %>
<%= line %>
<% end %>

编辑2 正在上传的文件在不包含逗号的行之后重复了标题(不要问)...所以我找到不包含逗号的行并调用 .gets (在我的 rb 脚本中独立于 Rails)。不幸的是,我收到一个关于 gets 是我无法调用的私有(private)方法的错误。这又回到了我最初的问题。文件不是具有像 read_lines 和 gets 这样的 IO 方法的 IO 子类吗?

        @file_out = []
        @file_in.each_line do |line|
            case line
            when /^[^,]+$/
                @comp = line.to_s.strip
                comp_header = @file_in.gets.strip.split('')

                @file_out.push(@comp)
            end
        end

最佳答案

当您发布 'file_field' 时,返回到 Controller 的参数具有一些特殊的魔力。

即在你的情况下你可以这样

<%= "The following file was uploaded #{params[:csv_file].original_filename}" %>
<%= "It's content type was #{params[:csv_file].content_type}" %>
<%= "The content of the file is as follows: #{params[:csv_file].read}" %>

因此,这些是您可以在 params[:csv_file] 上调用的三种特殊方法,或者在 View 中作为成功的“file_field_tag”或“f.file_field”结果发布的任何参数

请记住,这些是您可以对作为 file_field 发布的参数进行的三个额外特殊操作:

原始文件名

内容类型

阅读

您已经清楚地知道如何进行读取,original_filename 和 content_type 可能会在将来帮助您。

编辑

好的,所以你所拥有的就是 read 方法,它将读取上传的文件的内容。

contents = params[:csv_file].read

现在,contents 是一个包含文件内容的字符串,但除了它是一个 csv 文件之外,对该文件一无所知。我们知道 csv 是用 '\r' 分隔的(我想,我已经做了很多解析 csv 的工作,但我懒得去检查)

所以你可以这样做:

contents = params[:csv_file].read
contents.split("\r").each do |csvline|
  ???
end

编辑2

这是这篇文章的要点

当您将 file_field 发布到 Controller 时,对上传文件的内容最常见的操作是将其“读取”到 ruby​​ 字符串中。对上传内容的任何额外处理都必须在“read”返回的 ruby​​ 字符串上完成。

在这种特殊情况下,如果上传的文件始终是 CSV,您可以假设 CSV 并开始相应地解析它。如果您期望多种上传格式,则必须处理该问题,例如:

contents = params[:csv_file].read
case params[:csv_file].content_type
when 'txt/csv'
  contents.split("\r").each do |csvline| 
    ???
  end
when 'application/pdf'
  ???
end

关于ruby-on-rails - 有没有一个rails方法可以循环遍历上传文件的每一行? "each_line"是一个IO方法,但它不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14178396/

相关文章:

windows - 可自定义的 Windows 右键单击​​文件 uploader ?

django - 我可以在不使用 RAM 的情况下通过 HTML 表单将大图像上传到我的服务器吗?

ruby-on-rails - Webpacker 未实时编译

ruby-on-rails - Rails 4 Net::SMTPSyntaxError: 501 批量电子邮件的语法错误

ruby-on-rails - Curl::Error::Partial File Error: 传输部分文件错误

Python - move 和覆盖文件和文件夹

php - 多个文件上传 Angular + Laravel

ruby-on-rails - 显示字段的 Rails & Ransack 图标是可排序的

c - 在C中读取文件时忽略不必要的字符

java - 将文件中的值与数组进行比较