Ruby CSV.foreach从特定行开始

时间:2017-07-14 14:28:17

标签: ruby-on-rails ruby multithreading csv foreach

我看过几篇帖子没有真正的答案或过时的答案,所以我想知道是否有任何新的解决方案。我有一个巨大的CSV我需要读入。我不能在它上面调用open()它杀死我的服务器。我别无选择,只能使用.foreach()。

这样做,我的脚本需要6天才能运行。我想看看我是否可以通过使用线程并将任务分成两个或四个来减少它。因此,一个线程读取1-n行,同时一个线程将读取n + 1-end行。

所以我需要能够只在一个线程中读取文件的后半部分(后来如果我将其拆分为更多线程,只是通过特定行的特定行)。

Ruby中有没有这样做?这可以从某一行开始吗?

CSV.foreach(FULL_FACT_SHEET_CSV_PATH) do |trial|

修改 只是想知道我的一个线程是什么样的:

threads << Thread.new { 
CSV.open('matches_thread3.csv', 'wb') do |output_csv|

  output_csv << HEADER
  count = 1
  index = 0

    CSV.foreach(CSV_PATH) do |trial|
        index += 1
        if index > 120000 
            break if index > 180000
            #do stuff
        end
    end
end
}

但正如您所看到的,它必须迭代文件,直到它在开始之前记录120,000。因此,目标是通过开始在第120行读取来消除在行120,000之前读取所有行。

3 个答案:

答案 0 :(得分:0)

如果仍然有意义,则可以在{之后使用.with_index进行类似操作:

rows_array = []

CSV.foreach(path).with_index do |row, i|
  next if i == 0 #skip first row
  rows_array << columns.map { |n| row[n] }
end

答案 1 :(得分:0)

  

但是,正如您所看到的,它必须迭代文件,直到开始记录之前要记录120,000。因此,目标是通过开始读取120,000行来消除读取120,000行之前的所有行。

不可能。 CSV文件的内容只是一小块文本,带有一些逗号和换行符。您不知道N-1行在何处结束就无法知道文件N在哪个偏移处开始。要知道这一点,您必须知道N-1行从哪里开始(请参阅递归?)并读取文件,直到看到它的结尾为止(遇到不属于字段值的换行符)。

如果所有行的大小都固定,则例外。在这种情况下,您可以直接寻求偏移量120_000 * row_size。不过,我还没有看到这样的文件。

答案 2 :(得分:0)

根据我对Ruby问题的理解,它可能会对您有所帮助。

require 'csv'
csv_file = "matches_thread3.csv"
# define one Constant Chunk Size for Jobs
CHUNK_SIZE = 120000
# split - by splitting (\n) will generate an array of CSV records
# each_slice - will create array of records of CHUNK_SIZE defined

File.read(csv_file).split("\n").drop(1).each_slice(CHUNK_SIZE).with_index 
do |chunk, index|   

  data = []
   # chunk will be work as multiple Jobs of 120000 records 

  chunk.each do |row|
   data << r
   ##do stuff
  end
end