요청 은 정말 좋은 라이브러리입니다. 큰 파일 (> 1GB)을 다운로드하는 데 사용하고 싶습니다. 문제는 전체 파일을 메모리에 보관할 수 없다는 것입니다. 청크 단위로 읽어야합니다. 그리고 이것은 다음 코드의 문제입니다
import requests
def DownloadFile(url)
local_filename = url.split('/')[-1]
r = requests.get(url)
f = open(local_filename, 'wb')
for chunk in r.iter_content(chunk_size=512 * 1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
f.close()
return
어떤 이유로 든이 방법으로 작동하지 않습니다. 파일에 저장하기 전에 여전히 응답을 메모리에로드합니다.
최신 정보
FTP에서 큰 파일을 다운로드 할 수있는 작은 클라이언트 (Python 2.x /3.x)가 필요한 경우 여기에서 찾을 수 있습니다 . 멀티 스레딩 및 재 연결 (연결 모니터링)도 지원하며 다운로드 작업에 대한 소켓 매개 변수를 조정합니다.
답변
다음 스트리밍 코드를 사용하면 다운로드 한 파일의 크기에 관계없이 Python 메모리 사용이 제한됩니다.
def download_file(url):
local_filename = url.split('/')[-1]
# NOTE the stream=True parameter below
with requests.get(url, stream=True) as r:
r.raise_for_status()
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
# If you have chunk encoded response uncomment if
# and set chunk_size parameter to None.
#if chunk:
f.write(chunk)
return local_filename
사용하여 반환 된 바이트 수는 iter_content
정확히 chunk_size
; 종종 훨씬 더 큰 난수 일 것으로 예상되며 매 반복마다 다를 것으로 예상됩니다.
자세한 내용은 https://requests.readthedocs.io/en/latest/user/advanced/#body-content-workflow 및 https://requests.readthedocs.io/en/latest/api/#requests.Response.iter_content 를 참조 하십시오. 참고.
답변
당신이 사용하는 경우 그것은 훨씬 쉽게 Response.raw
와 shutil.copyfileobj()
:
import requests
import shutil
def download_file(url):
local_filename = url.split('/')[-1]
with requests.get(url, stream=True) as r:
with open(local_filename, 'wb') as f:
shutil.copyfileobj(r.raw, f)
return local_filename
이것은 과도한 메모리를 사용하지 않고 파일을 디스크로 스트리밍하며 코드는 간단합니다.
답변
아니 정확히 무엇 영업 이익은 요청했지만 … 그것과 그렇게 안되게 쉽게 urllib
:
from urllib.request import urlretrieve
url = 'http://mirror.pnl.gov/releases/16.04.2/ubuntu-16.04.2-desktop-amd64.iso'
dst = 'ubuntu-16.04.2-desktop-amd64.iso'
urlretrieve(url, dst)
또는 임시 파일로 저장하려면 다음과 같이하십시오.
from urllib.request import urlopen
from shutil import copyfileobj
from tempfile import NamedTemporaryFile
url = 'http://mirror.pnl.gov/releases/16.04.2/ubuntu-16.04.2-desktop-amd64.iso'
with urlopen(url) as fsrc, NamedTemporaryFile(delete=False) as fdst:
copyfileobj(fsrc, fdst)
나는 과정을 보았다 :
watch 'ps -p 18647 -o pid,ppid,pmem,rsz,vsz,comm,args; ls -al *.iso'
파일이 커지는 것을 보았지만 메모리 사용량은 17MB로 유지되었습니다. 뭔가 빠졌습니까?
답변
청크 크기가 너무 클 수 있습니다. 한 번에 1024 바이트를 떨어 뜨려 보셨습니까? (또한 with
구문을 정리하는 데 사용할 수 있습니다 )
def DownloadFile(url):
local_filename = url.split('/')[-1]
r = requests.get(url)
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
return
또한 응답이 메모리에로드되었다고 어떻게 추론하고 있습니까?
파이썬은 다른에서 파일의 데이터를 플러시되지 않은 것처럼 소리 SO 질문 당신이 시도 할 수 f.flush()
및 os.fsync()
파일 쓰기 및 사용 가능한 메모리를 강제로를;
with open(local_filename, 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
f.flush()
os.fsync(f.fileno())
답변
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)