2012-03-14 46 views
4

我正在尝试为Linux创建一个“下载管理器”,让我可以使用多线程下载单个文件。这就是我想要做的事:使用多线程下载单个文件

  1. 分割文件通过指定偏移
  2. 下载不同部分到一个临时位置
  3. 合并成一个单一的文件被下载到不同的部分。

步骤2和步骤3是可以解决的,步骤#1我卡住了。下载文件时如何指定偏移量?

沿着open("/path/to/file", "wb").write(urllib2.urlopen(url).read())的方向使用某些东西并不能让我指定一个读取的起始点。除此之外还有其他选择吗?

+1

你为什么要使用多线程下载?下载不会更快。 – 2012-03-14 12:13:10

+0

你不能使用多个文件并合并后?将文件保存在临时目录中的每个远程文件块,然后合并所有内容。 – hurtledown 2012-03-14 12:17:20

+0

@JakubZaverka:通常是这样。如果您尝试使用'wget'和像DownThemAll这样的下载管理器(用于Firefox)下载相同的文件,或者甚至尝试使用[this]的多线程'wget',您可以看到不同之处(http://stackoverflow.com /问题/ 4745799 /多wget的-RA-站点同时)。 – Vishnu 2012-03-14 12:17:56

回答

3

要下载文件的一部分,只需设置Range头这样

req = urllib2.Request(url) 
req.headers['Range'] = 'bytes=%s-%s' % (start, end) 
f = urllib2.urlopen(req) 

并非所有服务器支持的Range头虽然。大多数文件共享服务不。

3

首先,http服务器应该返回Content-Length标头。这通常意味着文件是一个静态文件,如果它是一个动态文件,比如php或者jsp的结果,则不能做这样的分割。

然后,你可以在请求时使用http Range头,这个头告诉服务器文件的哪一部分应该返回。请参阅python doc了解如何设置和解析http头。

要做到这一点,如果零件尺寸是100k,您首先请求范围:0-1000000 100k将获得第一部分,并在它的conent长度中响应告诉您文件的大小,然后启动一些线程不同的范围,它会工作