При загрузке больших файлов мы, предпочтительно использовать режим потоковой передачи при выполнении вызова get. Если мы используем параметр stream и устанавливаем его в True, загрузка не начнется немедленно. Загрузка файла начнется, когда мы попытаемся получить доступ к свойству контента или попытаться перебрать контент, используя iter_content / iter_lines.
Если для потока установлено значение False, весь контент сразу же загружается и помещается в память. Если размер файла большой, это может вскоре привести к проблемам с более высоким потреблением памяти. С другой стороны – если мы установили для Stream значение True, контент не загружается, но заголовки загружаются и соединение остается открытым. Теперь мы можем продолжить загрузку файла или просто отменить его.
Но мы также должны помнить, что если мы решим выполнить потоковую передачу файла, соединение останется открытым и не сможет вернуться в пул соединений. Если мы работаем со многими большими файлами, это может привести к некоторой потере эффективности. Таким образом, мы должны позаботиться о том, чтобы закрыть соединения и утилизировать любые неиспользуемые ресурсы в таких сценариях.
Установив параметр stream, мы задержали загрузку и избежали использования больших кусков памяти. Заголовки были загружены, но тело файла все еще ожидает извлечения. Теперь мы можем получить данные, обратившись к свойству контента или выбрав итерацию по контенту. Прямой доступ к контенту приведет к одновременному считыванию всех данных ответа в память. Это сценарий, который мы хотим избежать, когда наш целевой файл достаточно велик.
Таким образом, у нас остается выбор итерировать содержимое. Мы можем использовать iter_content, где содержимое будет читаться блоками. Или мы можем использовать iter_lines, где содержимое будет читаться построчно. В любом случае, весь файл не будет загружен в память и снизит использование памяти.
Пример:
1 2 3 4 5 |
response = requests.get(url, stream=True) handle = open(target_path, "wb") for chunk in response.iter_content(chunk_size=512): if chunk: # filter out keep-alive new chunks handle.write(chunk) |
Код максимально прост и понятен. Мы открываем URL с параметром stream, установленным в True. И затем мы открываем файл target_path и получаем дескриптор файла (в который мы хотим сохранить наш файл). Затем мы перебираем содержимое по частям и записываем данные в файл.