Мы разрешаем людям загружать файлы на S3, а затем выводим количество строк, количество строк в этом файле. Мы делаем это, запустив фоновый процесс (DelayedJob), который извлекает файл из S3, а затем подсчитывает количество новых строк в документе. В целом, это работает очень хорошо.Получение количества строк файла, размещенного на 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 предполагает, что вы не будете изменять этот буфер, так что это может отбросить все. –