Rails - 阅读上传的文本文件

时间:2016-05-03 04:42:36

标签: ruby-on-rails

我指的是stackoverflow帖子https://stackoverflow.com/a/2521135/2607331

了解如何阅读文件。

查看 -

<%= form_tag  ('/greetings/hello') do %>
  <label for="file">File to Upload</label> <%= file_field_tag "file" %>
  <div><%= submit_tag 'Process' %></div>
<% end %>

路线 -

Rails.application.routes.draw do
  post 'greetings/hello'

控制器 -

class GreetingsController < ApplicationController
def hello
  @filename = params[:file]

  if @filename.respond_to?(:read)
    @lines = file_data.read
  elsif @filename.respond_to?(:path)
    @lines = File.read(file_data.path)
  else
    logger.error "Bad file_data: #{@filename.class.name}: #    
    {@filename.inspect}"
  end
  render "hello"
 end
end

根据帖子,params [:file]将是一个临时文件或StringIO对象,但在我的例子中它是字符串。不确定出了什么问题。以下是记录器输出。

Started POST "/greetings/hello" for 183.83.51.8 at 2016-05-03 03:45:40 +0000
Cannot render console from 183.83.51.8! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by GreetingsController#hello as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"0r0Ny6rqlv9Gts1PBh+J4Dk7B+9WPea3HK1cgR/dWTLFrkXW+eggX+tie4wFs+F4lHM5RGpAHXL6EO3sKjd0sw==", "file"=>"sitcomquery.txt", "commit"=>"Process"}
Bad file_data: String: "sitcomquery.txt"
  Rendered greetings/hello.html.erb within layouts/application (5.6ms)
Completed 500 Internal Server Error in 97ms (ActiveRecord: 0.0ms)

修改

将index.html.erb更改为包含multipart -

<%= form_tag '/greetings/hello' ,multipart: true do %>
  <label for="file">File to Upload</label> <%= file_field_tag "file" %>
  <div><%= submit_tag 'Process' %></div>
<% end %>

在控制器中,我可以用 -

读取它
 tempfl = params[:file]
 @lines = tempfl.read

然而,@ lines是一个很大的字符串。我需要以@lines是行数组的方式阅读它。但是readlines不是ActionDispatch :: Http :: UploadedFile对象的方法。我是否需要保存文件并执行读取行,或者无论如何我都可以读取每一行而不保存文件。

3 个答案:

答案 0 :(得分:3)

您应该将多部分添加到表单中,就像下面的

一样
<!DOCTYPE html>
<html ng-app="esri-map-example">
    <head>
        <title>Angular Esri Quick Start</title>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
        <meta charset="utf-8">
      <script src="//npmcdn.com/angular-esri-map@2.0.0-beta.2"></script>
        <link rel="stylesheet" href="//js.arcgis.com/4.0beta3/esri/css/main.css">
    </head>
    <body ng-controller="MapController as vm">
        <esri-scene-view map="vm.map" view-options="{scale: 50000000, center: [-101.17, 21.78]}">
        </esri-scene-view>

        <!-- load Esri JSAPI -->
        <script src="//js.arcgis.com/4.0beta3/"></script>
        <!-- load AngularJS -->
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
        <!-- load angular-esri-map -->
        <script src="//npmcdn.com/angular-esri-map@2.0.0-beta.2"></script>

        <script type="text/javascript">
            angular.module('esri-map-example', ['esri.map'])
                .controller('MapController', function(esriLoader) {
                    var self = this;
                    esriLoader.require(['esri/Map'], function(Map) {
                        self.map = new Map({
                            basemap: 'streets'
                        });
                    });
                });
        </script>
    </body>
</html>

答案 1 :(得分:2)

class GreetingsController < ApplicationController
  def hello
    @filename = params[:file]

    if @filename.respond_to?(:read)
      @lines = file_data.read
    elsif @filename.respond_to?(:path)
      @lines = File.read(file_data.path)
    else
      logger.error "Bad file_data: #{@filename.class.name}: #    
                {@filename.inspect}"
    end
    render "hello"
  end
end

在这段代码中@filename包含一个字符串,并且你已经通过布尔函数respond_to检查了字符串包含方法是否读取?并且它总是会返回false,因为字符串没有方法读取。检查文件有很多选项,下面就是其中之一。

file = File.file?(params[:file])

if file
  @lines = File.read(params[:file])
else
 "your message"
end

如果您想将params文件作为IO对象读取,则需要在表单中添加multipart

<%= form_for(<object>, url: <path>, method: :post, remote: :true, html: {
  multipart: true, }) do |f| %>
    <input type="file" name="file_batch_upload" />
<% end %>

了解更多详情

https://stackoverflow.com/a/36765124/5715918

答案 2 :(得分:1)

问题是要读取每行上传的文件并逐行吐出。正常的readlines或each_line方法不起作用,因为Uploaded文件属于“UploadedFile”类,并且不支持IO方法。该解决方案可以在另一个stackoverflow帖子中找到 -

is there a rails method to loop through each line of uploaded file? "each_line" is an IO method but it's not working

谢谢!