我需要做的就是从CSV文件中获取标题.
file.csv是:
"A", "B", "C"
"1", "2", "3"
Run Code Online (Sandbox Code Playgroud)
我的代码是:
table = CSV.open("file.csv", :headers => true)
puts table.headers
table.each do |row|
puts row
end
Run Code Online (Sandbox Code Playgroud)
这给了我:
true
"1", "2", "3"
Run Code Online (Sandbox Code Playgroud)
我已经看了几个小时的Ruby CSV文档,这让我发疯.我确信必须有一个简单的单行程序可以将标题返回给我.有任何想法吗?
Dyl*_*kow 12
它看起来CSV.read会让您访问一个headers方法:
headers = CSV.read("file.csv", headers: true).headers
# => ["A", "B", "C"]
Run Code Online (Sandbox Code Playgroud)
以上只是一个捷径CSV.open("file.csv", headers: true).read.headers.您可以在CSV.open尝试时使用它,但由于CSV.open在调用方法时实际上并没有读取文件,因此在实际读取某些数据之前,它无法知道标题是什么.这就是为什么它只是true在你的例子中返回.读完一些数据后,最终会返回标题:
table = CSV.open("file.csv", :headers => true)
table.headers
# => true
table.read
# => #<CSV::Table mode:col_or_row row_count:2>
table.headers
# => ["A", "B", "C"]
Run Code Online (Sandbox Code Playgroud)
我认为最好的方法是:
headers = CSV.foreach('file.csv').first
请注意,使用它非常诱人,CSV.read('file.csv'. headers: true).headers但要注意的是,CSV.read将完整的文件加载到内存中,因此增加了内存占用,并且也使得使用大文件的速度非常慢。请尽可能使用CSV.foreach。以下是仅20 MB文件的基准测试:
Ruby version: ruby 2.4.1p111
File size: 20M
****************
Time and memory usage with CSV.foreach:
Time: 0.0 seconds
Memory: 0.04 MB
****************
Time and memory usage with CSV.read:
Time: 5.88 seconds
Memory: 314.25 MB
Run Code Online (Sandbox Code Playgroud)
20 MB文件的占用的内存增加了314 MB CSV.read,请想象一下1GB文件将对您的系统产生什么影响。简而言之,请不要使用CSV.read,我这样做了,系统崩溃了,容量为300MB。
进一步阅读:如果您想了解更多有关此的内容,这是一篇有关处理大文件的很好的文章。
以下也是我用于基准测试CSV.foreach和的脚本CSV.read:
require 'benchmark'
require 'csv'
def print_memory_usage
memory_before = `ps -o rss= -p #{Process.pid}`.to_i
yield
memory_after = `ps -o rss= -p #{Process.pid}`.to_i
puts "Memory: #{((memory_after - memory_before) / 1024.0).round(2)} MB"
end
def print_time_spent
time = Benchmark.realtime do
yield
end
puts "Time: #{time.round(2)} seconds"
end
file_path = '{path_to_csv_file}'
puts 'Ruby version: ' + `ruby -v`
puts 'File size:' + `du -h #{file_path}`
puts 'Time and memory usage with CSV.foreach: '
print_memory_usage do
print_time_spent do
headers = CSV.foreach(file_path, headers: false).first
end
end
puts 'Time and memory usage with CSV.read:'
print_memory_usage do
print_time_spent do
headers = CSV.read(file_path, headers: true).headers
end
end
Run Code Online (Sandbox Code Playgroud)