我们允许人们将文件上传到 S3,然后我们显示该文件中有多少行的行数。我们通过运行一个后台进程 (DelayedJob) 来做到这一点,该进程从 S3 获取文件,然后计算文档中换行符的数量。一般来说,这工作得很好。
这是完成工作的代码:
def self.line_count_from_s3(options={})
options = { :key => options } if options.is_a?(String)
line_count = 0
unless options[:key]
raise ArgumentError, 'A valid S3 key is required.'
end
s3 = AWS::S3.new
file = s3.buckets[ENV['S3_BUCKET']].objects[options[:key]]
unless file.exists?
raise IOError, 'Unable to load that import from S3. Key does not exist.'
end
# Stream download chunks of the file instead of loading it all into memory
file.read do |chunk|
# Normalize line endings
chunk.gsub!(/\r\n?/, "\n")
line_count += chunk.scan("\n").count
end
# Don't count the empty newline (assumes there is one)
line_count -= 1 if line_count > 0
line_count
end
出于某种原因,一些文件的行数完全错误。例如,一个有 10,000 行的文件显示的行数为 40,000。这并不一致。大多数文件都可以正常工作。
我试图弄清楚这是否可能是由 S3 分块阅读器的工作方式引起的,或者是否有其他原因导致了问题。知道为什么记录计数会出错吗?有没有更好的方法来做到这一点,我不知道?