Другие ответы в этой теме связаны с boto, но S3.Object больше не повторяется в boto3. Таким образом, следующее НЕ РАБОТАЕТ, оно выдает сообщение об ошибке TypeError: 's3.Object' object is not iterable
:
s3 = boto3.session.Session(profile_name=my_profile).resource('s3')
s3_obj = s3.Object(bucket_name=my_bucket, key=my_key)
with io.FileIO('sample.txt', 'w') as file:
for i in s3_obj:
file.write(i)
В boto3 содержимое объекта доступно в S3.Object.get()['Body']
, которое также не является итерируемым, поэтому следующий еще НЕ РАБОТАЕТ:
body = s3_obj['Body']
with io.FileIO('sample.txt', 'w') as file:
for i in body:
file.write(i)
Итак, альтернативой является использование метода чтения, но это загружает объект WHOLE S3 в память, который при работе с большими файлами не всегда возможен:
body = s3_obj['Body']
with io.FileIO('sample.txt', 'w') as file:
for i in body.read():
file.write(i)
Но метод read
позволяет передать в amt
параметр, определяющий количество байтов, которые мы хотим прочитать из базового потока. Этот метод можно многократно вызывать до тех пор, пока весь поток не будет прочитан:
body = s3_obj['Body']
with io.FileIO('sample.txt', 'w') as file:
while file.write(body.read(amt=512)):
pass
Копаем в код botocore.response.StreamingBody
, понимаем, что базовый поток также доступен, поэтому мы могли бы выполнять итерацию следующим образом:
body = s3_obj['Body']
with io.FileIO('sample.txt', 'w') as file:
for b in body._raw_stream:
file.write(b)
В то время как googling я также видел некоторые ссылки, которые могут быть использованы, но я не пробовал:
Может быть важно, что Perl никогда не отдает память к системе отдельно: это - все до malloc()
и все правила, связанные с этим.
Знание, как malloc()
выделяет память, важно для ответа на больший вопрос, и это варьируется от системы до системы, но в целом большинства malloc()
реализации оптимизированы для выделения программ и освобождения в подобных стеку заказах. Perl использует подсчет ссылок для отслеживания памяти, что означает, что освобождение, что означает (в отличие от основанного на GC языка, который использует malloc()
внизу) это - на самом деле не все, что трудный сказать, куда освобождение собирается произойти, и в какой порядок.
Может случиться так, что можно реорганизовать программу для использования в своих интересах этого факта - путем вызова undef($old_object)
явно - и в правильном порядке, способом, подобным пути, C-программисты говорят free(old_object);
Для продолжительных программ (дни, месяцы, и т.д.), где у меня есть загрузки циклов загрузки/копии/дампа, я собираю "мусор" с помощью exit() and exec()
, и где это otherwide невыполнимый, я просто собираю свои структуры данных (использование Storable
) и дескрипторы файлов (использование $^F
) и exec($0)
- обычно с набором переменной среды как $ENV{EXEC_GC_MODE}
, и Вам, возможно, понадобится что-то подобное, даже если у Вас нет собственных утечек просто, потому что Perl пропускает маленькие блоки что Ваша система malloc()
не может выяснить, как отдать.
Конечно, если у Вас действительно есть утечки в Вашем коде, затем остальная часть моего совета несколько более релевантна. Это было первоначально отправлено на другой вопрос на этом предмете, но это явно не покрывало продолжительные программы.
Все утечки памяти программ жемчуга или будут XS, содержащим на ссылку или круговую структуру данных. Devel:: Цикл является большим инструментом для нахождения циклических ссылок, если Вы знаете, какие структуры, вероятно, будут содержать циклы. Devel:: Быстрый взгляд может использоваться для нахождения объектов с более высоким, чем ожидалось подсчетом ссылок.
Если Вы не знаете, где еще посмотреть, Devel:: LeakTrace:: Быстро могло быть хорошее первое место, но Вам будет нужен жемчуг, созданный для отладки.
Если Вы подозреваете, что утечкой является внутреннее XS-пространство, это намного более твердо, и Valgrind, вероятно, будет Вашим лучшим выбором. Тест:: Valgrind может помочь Вам понизить объем кода, который необходимо искать, но это не будет работать над Windows, таким образом, необходимо было бы портировать (по крайней мере, текучая часть) к Linux, чтобы сделать это.
Devel:: Гладиатор является другим полезным инструментом в этом пространстве.
Походит на cpan модуль Devel:: Цикл - то, что Вы ищете. Это требует внесения некоторых изменений в Ваш код, но это должно помочь Вам найти свои ссылки без слишком многих проблем.
valgrind является большим приложением Linux, которое определяет местоположение утечек памяти в рабочем коде. Если Ваш код Perl работает на Linux, необходимо проверить его.