0

Rails でアップロードされたファイルの各行を読み取ろうとしています。

file_data = params[:files]
    if file_data.respond_to?(:read)
      file_data.read.gsub( /\n/, "\r\n" ).split("\r\n").each do |line|
        inputUsers.push(line.strip)
      end
    elsif file_data.respond_to?(:path)
      File.read(file_data.path).gsub( /\n/, "\r\n" ).split("\r\n").each do |line|
       inputUsers.push(line.strip)
     end

アップロードされたファイルに Windows と Unix のエンコーディングが混在している場合、おそらく複数の場所からコピーしたことが原因で、Rails はファイルの各行を適切に区切らず、2 行を 1 行として返すことがあります。

アプリケーションは Linux ボックスでホストされています。また、ファイルは Google ドキュメントのスプレッドシートの列からコピーされます。

この問題の解決策はありますか?


編集:

新しい行に分割されない行の 16 進コードは次のようになります。

636f 6d0d 0a4e 6968
4

3 に答える 3

2

これが私がこれについて行く方法です。まず、いくつかのコードをテストするには:

SAMPLE_TEXT = [
  "now\ris\r\nthe\ntime\n",
  "for all good men\n"
]

def read_file(data)
  data.each do |li|                       
    [ *li.split(/[\r\n]+/) ].each do |l|  
      yield l                             
    end                                   
  end                                     
end

read_file(SAMPLE_TEXT) do |li|
  puts li                       
end                             

どの出力:

now
is
the
time
for all good men

で魔法が発生し[ *li.split(/[\r\n]+/) ]ます。それを分解する:

  • li.split(/[\r\n]+/)改行、改行、およびそれらの組み合わせで行が分割されます。行に倍数がある場合、コードは空の行を飲み込みます。そのため、それらを受け取る可能性がある場合は、もう少し洗練されたパターンが必要になります。これはテストされていませんが/[\r\n]{1,2}/、機能するはずです。
  • *li.split(/[\r\n]+/)*次の配列をその構成要素に分解することを示す「splat」演算子を使用します。これは、メソッドに渡される要素が 1 つなのか配列なのかがわからない場合に、配列を取得する便利な方法です。
  • [*li.split(/[\r\n]+/)]返されたコンポーネントを受け取り、単一の配列に戻します。

代わりにファイルを処理するようにメソッドを変更するのは簡単です:

def read_file(fname)
  File.foreach(fname) do |li|
    [ *li.split(/[\r\n]+/) ].each do |l|
      yield l
    end
  end
end

前の例とほぼ同じ方法で呼び出します。

read_file('path/to/file') do |li|
  puts li                       
end                             

使用する理由は、行ごとに読み取るためです。これは、またはforeachを使用してファイルを丸呑みするよりもはるかにメモリ効率が高く、どちらもファイル全体を一度にメモリに読み込みます。また、非常に高速であるため、使用時に速度が低下することはありません。その結果、型のメソッドにはほとんど利点がなく、 を使用する利点は十分にあります。readreadlinesforeachreadforeach

于 2013-09-24T16:46:29.840 に答える
1

これは、Windows ファイルを解析するときに問題になります\n。になり\r\nました。\r\n\r\r\n

Unix の行末形式に置き換えてから、次のように分割することをお勧めし\nます。

file_data.read.gsub( /\n/, "\r\n" ).split("\r\n").each do |line|

になります:

file_data.read.gsub( /\r\n/, "\n" ).split("\n").each do |line|
于 2013-09-24T14:41:33.110 に答える