Python: Сообщение HTTP большой файл с потоковой передачей

Я загружаю потенциально большие файлы на веб-сервер. В настоящее время я делаю это:

import urllib2

f = open('somelargefile.zip','rb')
request = urllib2.Request(url,f.read())
request.add_header("Content-Type", "application/zip")
response = urllib2.urlopen(request)

Однако это читает содержание всего файла в память прежде, чем отправить его. Как у меня может быть он, передают файл потоком к серверу?

16
задан Daniel Von Fange 23 March 2010 в 18:31
поделиться

3 ответа

Просматривая цепочку рассылки, на которую ссылается systempuntoout, я нашел ключ к решению.

Модуль mmap позволяет открывать файл, который действует как строка. Части файла загружаются в память по запросу.

Вот код, который я сейчас использую:

import urllib2
import mmap

# Open the file as a memory mapped string. Looks like a string, but 
# actually accesses the file behind the scenes. 
f = open('somelargefile.zip','rb')
mmapped_file_as_string = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)

# Do the request
request = urllib2.Request(url, mmapped_file_as_string)
request.add_header("Content-Type", "application/zip")
response = urllib2.urlopen(request)

#close everything
mmapped_file_as_string.close()
f.close()
28
ответ дан 30 November 2019 в 16:49
поделиться

Попробуйте pycurl. У меня ничего нет, установка примет большой файл, который не в POST multipart / form-data, но вот простой пример, который читает файл по мере необходимости.

import os
import pycurl

class FileReader:
    def __init__(self, fp):
        self.fp = fp
    def read_callback(self, size):
        return self.fp.read(size)

c = pycurl.Curl()
c.setopt(pycurl.URL, url)
c.setopt(pycurl.UPLOAD, 1)
c.setopt(pycurl.READFUNCTION, FileReader(open(filename, 'rb')).read_callback)
filesize = os.path.getsize(filename)
c.setopt(pycurl.INFILESIZE, filesize)
c.perform()
c.close()
1
ответ дан 30 November 2019 в 16:49
поделиться

Вы пробовали использовать Mechanize ?

from mechanize import Browser
br = Browser()
br.open(url)
br.form.add_file(open('largefile.zip'), 'application/zip', 'largefile.zip')
br.submit()

или, если вы не хотите использовать multipart / form-data, проверьте эту старую публикацию.

Предлагаются два варианта:

  1. Use mmap, Memory Mapped file object
  2. Patch httplib.HTTPConnection.send
3
ответ дан 30 November 2019 в 16:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: