2011-03-30 26 views
4

我寫了一個python腳本,我正用它從HTTP服務器下載大量的視頻文件(每個文件大小爲50-400 MB)。到目前爲止,它在長長的下載列表中運行良好,但由於某些原因,它很少出現內存錯誤。Python:下載大文件時出現無法預知的內存錯誤

該機器擁有大約1 GB的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 

回答

8

你的問題是在這裏:f.read()。該行嘗試將整個文件下載到內存中。取而代之的是,閱讀塊(chunk = f.read(4096)),並將其保存到臨時文件。

+0

你怎麼知道你什麼時候完成下載?或整體數據的長度?該文檔沒有任何關於'f.read()'返回的對象的信息。 – 2011-03-31 23:03:55

+2

您需要查看「Content-length」標題。 – 2011-03-31 23:06:55

相關問題