【问题标题】:Getting the line count of a file hosted on S3获取托管在 S3 上的文件的行数
【发布时间】:2013-07-27 01:51:38
【问题描述】:

我们允许人们将文件上传到 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 分块阅读器的工作方式引起的,或者是否有其他原因导致了该问题。知道为什么记录计数会出错吗?有没有我不知道的更好的方法来做到这一点?

【问题讨论】:

  • 所有文件的格式都一样吗?
  • 现在它们都是相同的 CSV 格式,但是很快就会改变。至于文件编码,一般为UTF8、win32或ASCII文件。我们使用 gsub(/\r\n?/, "\n") 来规范化文件块中的行尾,然后再计算它们。
  • 同一个文件是否总是产生相同的错误计数。您是否尝试过不就地变异块?看起来 net/http 假设你不会修改这个缓冲区,所以这可能会丢掉东西。
  • 我试图通过使用 AWS lambda 做同样的事情,所以每当文件到达时,它都会计算记录数,我在 python 中运行 shell 命令,并收到错误“OSError : [Errno 7] 参数列表太长”。你有没有找到一种方法来做到这一点而不会出错。

标签: ruby amazon-web-services amazon-s3 chunking


【解决方案1】:

我不知道您为什么将line_count 初始化为0 并执行+=。你不需要它。您的计数程序将简化为:

file.read do |chunk|
  chunk.gsub!(/\r\n?/, "\n")
  line_count = chunk.count("\n")
end

【讨论】:

  • 我们分块读取文件,而不是一次读取整个文件。我的印象是每个块只代表文件的一部分,这就是我们将每个块的行数加在一起的原因。不对吗?
  • 我明白了。但我没有看到任何迭代块的例程。
  • 如果您将一个块传递给 S3Object.read,它会自动分块下载:docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html
猜你喜欢
  • 2011-11-18
  • 1970-01-01
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 2015-09-08
相关资源
最近更新 更多