복붙노트

[PYTHON] 파이썬 : HTTP 스트리밍으로 큰 파일 게시

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)

그러나 게시하기 전에 전체 파일의 내용을 메모리로 읽습니다. 파일을 서버로 스트리밍 할 수 있습니까?

해결법

  1. ==============================

    1.systempuntoout에 링크 된 메일 링리스트 스레드를 통해 읽었을 때, 해결책에 대한 단서를 발견했습니다.

    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()
    
  2. ==============================

    2.Mechanize로 해봤습니까?

    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. ==============================

    3.설명서에서는이 작업을 수행 할 수 있다고 말하지 않지만 urllib2 (및 httplib)의 코드는 read () 메서드가있는 객체를 데이터로 허용합니다. 따라서 열린 파일을 사용하는 것이 트릭을 수행하는 것 같습니다.

    설명서에서는이 작업을 수행 할 수 있다고 말하지 않지만 urllib2 (및 httplib)의 코드는 read () 메서드가있는 객체를 데이터로 허용합니다. 따라서 열린 파일을 사용하는 것이 트릭을 수행하는 것 같습니다.

    Content-Length 헤더를 직접 설정해야합니다. 설정되어 있지 않으면 urllib2는 파일 객체가 지원하지 않는 데이터에 대해 len ()을 호출합니다.

    import os.path
    import urllib2
    
    data = open(filename, 'r')
    headers = { 'Content-Length' : os.path.getsize(filename) }
    response = urllib2.urlopen(url, data, headers)
    

    이것은 사용자가 제공 한 데이터를 처리하는 관련 코드입니다. 그것은 Python 2.7의 httplib.py에있는 HTTPConnection 클래스에서 왔습니다.

    def send(self, data):
        """Send `data' to the server."""
        if self.sock is None:
            if self.auto_open:
                self.connect()
            else:
                raise NotConnected()
    
        if self.debuglevel > 0:
            print "send:", repr(data)
        blocksize = 8192
        if hasattr(data,'read') and not isinstance(data, array):
            if self.debuglevel > 0: print "sendIng a read()able"
            datablock = data.read(blocksize)
            while datablock:
                self.sock.sendall(datablock)
                datablock = data.read(blocksize)
        else:
            self.sock.sendall(data)
    
  4. ==============================

    4.pycurl을 시도하십시오. 설치 프로그램이 multipart / form-data POST가 아닌 큰 파일을 받아 들일 수있는 것은 없지만 필요한 경우 파일을 읽는 간단한 예제가 있습니다.

    pycurl을 시도하십시오. 설치 프로그램이 multipart / form-data POST가 아닌 큰 파일을 받아 들일 수있는 것은 없지만 필요한 경우 파일을 읽는 간단한 예제가 있습니다.

    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()
    
  5. ==============================

    5.요청 라이브러리를 사용하면 할 수 있습니다.

    요청 라이브러리를 사용하면 할 수 있습니다.

    with open('massive-body', 'rb') as f:
        requests.post('http://some.url/streamed', data=f)
    

    문서에서 언급 한 것처럼

  6. ==============================

    6.Brian의 답변에 대해 (아직) 의견을 말할 수는 없습니다 https://stackoverflow.com/a/30810626/9921853

    Brian의 답변에 대해 (아직) 의견을 말할 수는 없습니다 https://stackoverflow.com/a/30810626/9921853

    urllib2.urlopen (url, data, headers)는 매개 변수로 헤더를 사용하지 않으므로 작동하지 않습니다.

    다음은 Python 2 / Python 3의 작동 예제입니다.

    try:
        from urllib2 import urlopen, Request
    except:
        from urllib.request import urlopen, Request
    
    headers = { 'Content-length': str(os.path.getsize(filepath)) }
    with open(filepath, 'rb') as f:
        req = Request(url, data=f, headers=headers)
        result = urlopen(req).read().decode()
    

    요청 모듈은 훌륭하지만 때로는 추가 모듈을 설치할 수없는 경우가 있습니다 ...

  7. from https://stackoverflow.com/questions/2502596/python-http-post-a-large-file-with-streaming by cc-by-sa and MIT license