Dan*_*nge 16 python http urllib2
我正在将可能很大的文件上传到Web服务器.目前我这样做:
import urllib2
f = open('somelargefile.zip','rb')
request = urllib2.Request(url,f.read())
request.add_header("Content-Type", "application/zip")
response = urllib2.urlopen(request)
Run Code Online (Sandbox Code Playgroud)
但是,这会在发布之前将整个文件的内容读入内存.我怎样才能将文件流式传输到服务器?
Dan*_*nge 28
阅读通过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()
Run Code Online (Sandbox Code Playgroud)
小智 5
文档并没有说你可以这样做,但是 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)
Run Code Online (Sandbox Code Playgroud)
这是处理您提供的数据的相关代码。它来自Python 2.7HTTPConnection中的类httplib.py:
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
25240 次 |
| 最近记录: |