我写了一个 python 脚本,我用它从 HTTP 服务器下载大量视频文件(每个 50-400 MB)。到目前为止,它在长长的下载列表上运行良好,但由于某种原因,它很少出现内存错误。
机器有大约 1 GB 的可用 RAM,但我认为在运行此脚本时它的 RAM 从未达到极限。
我在任务管理器和 perfmon 中监控了内存使用情况,它的行为与我所看到的始终相同:在下载过程中缓慢增加,然后在完成下载后恢复到正常水平(没有小泄漏爬起来或类似的东西)。
下载的行为方式是创建文件,该文件在下载完成(或程序崩溃)之前保持为 0 KB,然后立即写入整个文件并关闭它。
for i in range(len(urls)):
if os.path.exists(folderName + '/' + filenames[i] + '.mov'):
print 'File exists, continuing.'
continue
# Request the download page
req = urllib2.Request(urls[i], headers = headers)
sock = urllib2.urlopen(req)
responseHeaders = sock.headers
body = sock.read()
sock.close()
# Search the page for the download URL
tmp = body.find('/getfile/')
downloadSuffix = body[tmp:body.find('"', tmp)]
downloadUrl = domain + downloadSuffix
req = urllib2.Request(downloadUrl, headers = headers)
print '%s Downloading %s, file %i of %i'
% (time.ctime(), filenames[i], i+1, len(urls))
f = urllib2.urlopen(req)
# Open our local file for writing, 'b' for binary file mode
video_file = open(foldername + '/' + filenames[i] + '.mov', 'wb')
# Write the downloaded data to the local file
video_file.write(f.read()) ##### MemoryError: out of memory #####
video_file.close()
print '%s Download complete!' % (time.ctime())
# Free up memory, in hopes of preventing memory errors
del f
del video_file
这是堆栈跟踪:
File "downloadVideos.py", line 159, in <module>
main()
File "downloadVideos.py", line 136, in main
video_file.write(f.read())
File "c:\python27\lib\socket.py", line 358, in read
buf.write(data)
MemoryError: out of memory
最佳答案
你的问题在这里:f.read()
。该行尝试将整个文件下载到内存中。取而代之的是,读取 block (chunk = f.read(4096)
),并将片段保存到临时文件。
关于Python:下载大文件时出现不可预测的内存错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5492797/