打印 上一主题 下一主题 利用cURL实现单个文件分多段同时下载,支持断点续传(修订版)

Posted LiuYanYGZ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打印 上一主题 下一主题 利用cURL实现单个文件分多段同时下载,支持断点续传(修订版)相关的知识,希望对你有一定的参考价值。

 
技术分享 技术分享 技术分享

利用cURL实现单个文件分多段同时下载,支持断点续传(修订版) [复制链接]

摘自 http://bbs.chinaunix.net/thread-917952-1-1.html

 

在ubuntu下测试通过, 适合在支持多线程下载的站点下载文件
可以配合flashgot在firefox中使用

用法:./mycurl url [referedUrl]
第一个参数url是要下载的文件的地址,第二个参数referedUrl是指需要参照的网址(一般不需要,有些网站,比如华军需要此参数)
例如:
./mycurl ftp://xx.xxx.xxx/xxx.rar
或者
./mycurl http://xx.xxx.xx/xxx.rar http://www.xxx.xxx/yy.htm

下面是代码:

#!/bin/bash
####################################################################
#
# Script for curl to support resumable multi-part download.
#
# Tested on Ubuntu
#

url=$1

# How many "parts" will the target file be divided into?
declare -i parts=5

read -ep "Please input the target directory: " targetdir
read -ep "Please input the outfile name: " outfile

[ -z "$targetdir" ] && targetdir="./"
cd $targetdir||exit 2

[ -z "$outfile" ] && outfile=`basename $1`

#Set the referer url
if [ -n "$2" ]; then
    refurl="-L -e $2"
else refurl=""
fi

length=`curl $refurl -s -I $url|grep Content-Length|tail -n 1|sed s/[^0-9]//g`

if [ -z "$length" ]; then
        echo "cann‘t get the length of the target file"
        exit 1
fi
let "length = $length"

#lsession is used to record how many bytes of each subpart should be downloaded
declare -i lsession=$(($length/$parts))

finished="false"

#Assume the available maximum connections on server can reach "parts" at first
maxconn=$parts

while true;
do

for (( i=1; i<=parts ; i=i+1 ))
do

#Array offsetold is used to record how many bytes have been downloaded of each subpart

    if [ -e $outfile$i ]; then
                offsetold[$i]=`ls -l $outfile$i|awk ‘{print $5}‘`
        else offsetold[$i]=0
        fi
        let "offsetold[$i] = ${offsetold[$i]}"

done

curr=0

for (( i=1; i<=parts && maxconn>0; i=i+1 ))
do

        if [ $i -lt $parts ]; then
                if [ ${offsetold[$i]} -lt $lsession ]; then      
                        curl $refurl -r $(($curr+${offsetold[$i]}))-$(($curr+$lsession-1)) $url >> $outfile$i &
            maxconn=$(($maxconn-1))
                fi
        else
                if [ ${offsetold[$i]} -lt $(($length-$(($lsession*$(($parts-1)))))) ]; then
                        curl $refurl -r $(($curr+${offsetold[$i]}))- $url >> $outfile$i &
            maxconn=$(($maxconn-1))
                fi
        fi
              
        curr=$(($curr+$lsession))                     

done


#To wait for all curl processes to terminate.

wait

finished="true"
maxconn=0
for (( i=1; i<=parts; i=i+1 ))
do

#Array offsetnew is used to record how many bytes have been downloaded of each subpart

        if [ -e $outfile$i ]; then
                offsetnew[$i]=`ls -l $outfile$i|awk ‘{print $5}‘`
        else offsetnew[$i]=0
        fi              
        let "offsetnew[$i] = ${offsetnew[$i]}"
        if [ $i -lt $parts ]; then
                if [ ${offsetnew[$i]} -lt $lsession ]; then
                        finished="false"
                fi
        else
                if [ ${offsetnew[$i]} -lt $(($length-$(($lsession*$(($parts-1)))))) ]; then
                        finished="false"
                fi
        fi

#Calculate the "real" available maximum connections supported by server

    if [ ${offsetnew[$i]} -gt ${offsetold[$i]} ]; then
        maxconn=$(($maxconn+1))   
    fi
done

        if [ "$finished" == "true" ]; then
                break
    elif [ $maxconn -eq 0 ]; then
        echo "Some errors may occur. retry 10 sec later..."
        sleep 10
        maxconn=parts
        fi
done

echo "All parts have been downloaded. Merging..."

mv --backup=t $outfile"1" $outfile
for (( i=2; i<=parts; i=i+1))
do
        cat $outfile$i >> $outfile
        rm $outfile$i
done

echo "Done."

[ 本帖最后由 ypxing 于 2007-4-4 21:45 编辑 ]

 
钢七连
不抛弃,不放弃
http://ypxing.cublog.cn/
   
   

家境小康

技术分享

帖子
1597
主题
14
精华
0
可用积分
1679
信誉积分
100
专家积分
0
在线时间
56 小时
注册时间
2004-12-13
最后登录
2011-04-28
论坛徽章:
0
2[报告]
 
技术分享 发表于 2007-04-01 11:01:09 |只看该作者
支持一下,这个脚本实用价值很好(2004年到现在的第一帖……)。

提两个建议:
1. 接收curl的参数,这样才是一个完整的curl壳。
2. 等待本shell脚本所起的后台进程全部完成,用wait,既准确又简洁。
另外,随着您的shell功力提高,您可以自己尝试着修整该脚本,相信也会有所收获。

PS:有个真正的多线程(这个脚本是多进程下载)命令行下载工具axel,据说不错,但我没用过,可以一试。
 
SUN E4500/SUN F4800/SUN V880
Solaris 8
KSH/NAWK/SED/VIM 6.3.3/perl 5.005_03
   
 

家境小康

技术分享

帖子
1276
主题
40
精华
4
可用积分
1470
信誉积分
102
专家积分
130
在线时间
1 小时
注册时间
2004-11-19
最后登录
2012-06-22
论坛徽章:
0

3[报告]

 
技术分享 发表于 2007-04-01 11:21:53 |只看该作者

回复 2楼 一梦如是 的帖子

谢谢大侠指点, 学习中...
俺也去试试axel
 

钢七连
不抛弃,不放弃
http://ypxing.cublog.cn/

 

 



大富大贵

技术分享技术分享技术分享

帖子
3040
主题
480
精华
1
可用积分
17274
信誉积分
1220
专家积分
5
在线时间
2434 小时
注册时间
2005-08-30
最后登录
2016-06-13
论坛徽章:
84
技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享技术分享
4[报告]
 
技术分享 发表于 2007-04-01 11:23:22 |只看该作者
curl 没用过,不过这么好的想法,,顶一下!
 
慷慨陈词,岂能皆如人意,鞠躬尽瘁,但求无愧我心。
stay hungry, stay foolish
https://github.com/tcler
http://www.tldp.org/LDP/abs/html
   
 

丰衣足食

技术分享

帖子
8343
主题
245
精华
1
可用积分
726
信誉积分
195
专家积分
15
在线时间
411 小时
注册时间
2006-09-18
最后登录
2013-08-16
论坛徽章:
0

5[报告]

 
技术分享 发表于 2007-04-01 14:21:48 |只看该作者
哇,支持!
 

爱家、爱国、爱和平、爱自由、爱生活、爱大自然!

 

 



丰衣足食

技术分享

帖子
154
主题
17
精华
0
可用积分
748
信誉积分
238
专家积分
0
在线时间
76 小时
注册时间
2005-04-01
最后登录
2016-06-06
论坛徽章:
0
6[报告]
 
技术分享 发表于 2007-04-01 19:28:31 |只看该作者
顶,佩服+羡慕楼主

我的习惯是下大文件用wget,小文件直接用firefox的下载器,有的站点单线程不快的话,就无能为力了
 
   
 

家境小康

技术分享

帖子
1276
主题
40
精华
4
可用积分
1470
信誉积分
102
专家积分
130
在线时间
1 小时
注册时间
2004-11-19
最后登录
2012-06-22
论坛徽章:
0

7[报告]

 
技术分享 发表于 2007-04-01 21:50:06 |只看该作者
一开始写这个script是为了和flashgot配合,在firefox里使用来者,呵呵
我也经常用wget的



原帖由 mmx384 于 2007-4-1 19:28 发表
顶,佩服+羡慕楼主

我的习惯是下大文件用wget,小文件直接用firefox的下载器,有的站点单线程不快的话,就无能为力了
 

钢七连
不抛弃,不放弃
http://ypxing.cublog.cn/

 

 



家境小康

技术分享

帖子
792
主题
43
精华
0
可用积分
1714
信誉积分
172
专家积分
0
在线时间
101 小时
注册时间
2004-03-14
最后登录
2013-09-28
论坛徽章:
0
8[报告]
 
技术分享 发表于 2007-04-01 23:38:42 |只看该作者
ASUSW3Z-W3HT30; DELL Lattitude D630; ThinkPadX61 7675C ; DELL OPTIPLEX-755
   
 

家境小康

技术分享

帖子
1276
主题
40
精华
4
可用积分
1470
信誉积分
102
专家积分
130
在线时间
1 小时
注册时间
2004-11-19
最后登录
2012-06-22
论坛徽章:
0

9[报告]

 
技术分享 发表于 2007-04-02 11:09:10 |只看该作者
谢谢
用他们提供的库可以开发更友好,功能更复杂的东东,有时间要试一下的

原帖由 baif 于 2007-4-1 23:38 发表
http://pycurl.sourceforge.net/
 

钢七连
不抛弃,不放弃
http://ypxing.cublog.cn/

 

 



 

家境小康

技术分享

帖子
1276
主题
40
精华
4
可用积分
1470
信誉积分
102
专家积分
130
在线时间
1 小时
注册时间
2004-11-19
最后登录
2012-06-22
论坛徽章:
0
10[报告]
 
技术分享 发表于 2007-04-03 21:28:23 |只看该作者
修改了一下原来的脚本
1. 用wait等待后台进程的完成
2. 避免了对不支持多线程下载的站点多次重复连接

通过修改写过的脚本确实可以学到更多东西

原帖由 一梦如是 于 2007-4-1 11:01 发表
支持一下,这个脚本实用价值很好(2004年到现在的第一帖……)。

提两个建议:
1. 接收curl的参数,这样才是一个完整的curl壳。
2. 等待本shell脚本所起的后台进程全部完成,用wait,既准确又简洁。
另外, ...
 
钢七连
不抛弃,不放弃
http://ypxing.cublog.cn/

以上是关于打印 上一主题 下一主题 利用cURL实现单个文件分多段同时下载,支持断点续传(修订版)的主要内容,如果未能解决你的问题,请参考以下文章

WordPress主题开发:实现分页功能

Drupal 主题化视图显示中的一行

jupyter notebook写Python,修改主题后,打印出来的内容显示不全怎么解决呢?谢谢!

如何将带有主题和扩展名的 ACE 编辑器存储在单个文件中?

Curl:修复 CURL (51) SSL 错误:没有替代证书主题名称匹配

vuejs 在单个文件 vue 组件中具有范围 css 的多个主题