利用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实现单个文件分多段同时下载,支持断点续传(修订版)的更多相关文章

  1. 利用struts2进行单个文件,批量文件上传,ajax异步上传以及下载

    利用struts2进行单个文件,批量文件上传,ajax异步上传以及下载 1.页面显示代码 <%@ page language="java" import="java ...

  2. 【FTP】FTP文件上传下载-支持断点续传

    Jar包:apache的commons-net包: 支持断点续传 支持进度监控(有时出不来,搞不清原因) 相关知识点 编码格式: UTF-8等; 文件类型: 包括[BINARY_FILE_TYPE(常 ...

  3. 文件的上传(可以上传照片,word文档,等单个文件)

    jsp: jsp页面: <LINK href="${basePath}plugins/uploadify/uploadify.css" type="text/css ...

  4. 苹果电脑利用curl下载数据集

    在看tensorflow书上迁徙学习的这一部分的时候,书上说利用 curl http://download.tensorflow.org/example_images/flower_photos.tg ...

  5. cesium结合geoserver利用WFS服务实现图层编辑(附源码下载)

    前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...

  6. cesium结合geoserver利用WFS服务实现图层删除(附源码下载)

    前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...

  7. Pacman主题下给Hexo增加简历类型

    原文 http://blog.zanlabs.com/2015/01/02/add-resume-type-to-hexo-under-pacman-theme/ 背景 虽然暂时不找工作,但是想着简历 ...

  8. Hexo快速构建个人小站-Fulid主题下添加Valine评论系统(三)

    Hexo目录: Hexo快速构建个人小站-Hexo初始化和将项目托管在Github(一) Hexo快速构建个人小站-自定义域名和自定义主题(二) 背景交代: 前面两章完成了Hexo的初始化和部分自定义 ...

  9. Java: 在不同windows主题下,JFrame窗口设置最佳高度的解决方案

    //设置窗口的大小,无论使用怎样的windows主题,都能灵活的应对,显示合适的窗口大小,一定要在JFrame.setVisible(true)之前调用, //替代传统的frame.setSize(w ...

随机推荐

  1. bzoj1644 [Usaco2007 Oct]Obstacle Course 障碍训练课

    Description 考虑一个 N x N (1 <= N <= 100)的有1个个方格组成的正方形牧场.有些方格是奶牛们不能踏上的,它们被标记为了'x'.例如下图: . . B x . ...

  2. jQuery UI 之 EasyUI 快速入门

    jQuery EasyUI 基础 转载自(http://www.shouce.ren/api/view/a/3350) jQuery EasyUI 是一个基于 jQuery 的框架,集成了各种用户界面 ...

  3. Unity 制作RPG地图2(自己控制地图上图标)

    上一次用Unity摄像机方式实现了地图的制作,现在介绍另一种实现地图的方式: 自己通过代码实现小地图NCP图标的显示和隐藏 制作地图的步骤: 1. 根据游戏人物的3D坐标转换成2D平面坐标,根据距离显 ...

  4. 让man 显示中文

    1.添加库函数手册 ubuntu默认是没有安装c语言的库函数man手册的,所以你在man perror 和sendto之类的函数时会显示没有相关文档的问题,这个问题让我郁闷了我好久.解决方法: sud ...

  5. 【后缀数组】【poj2774】【 Long Long Message】

    题意: 求两个串的最长连续子串. 我的想法: 枚举第二个串...在第一个串的后缀数组中二分查找. 复杂度NlogN.最坏情况N^2 题解: (3)height 数组:定义height[i]=suffi ...

  6. 流媒体开发之--HLS--M3U8解析(2): HLS草案

    目录 1 简介 2 2 概述 2 3 播放列表文件 3 3.1 介绍 3 3.2新标签 4 3.2.1 EXT-X-TARGETDURATION 4 3.2.2 EXT-X-MEDIA-SEQUENC ...

  7. 配置基于NotePad++工具下的C#开发环境

    1.打开NotePad++,打开Notepad++的插件(plugins)菜单-->Plugin Manager-->Show Plugin Manager-->勾选NppExec- ...

  8. jQuery中两种阻止事件冒泡的区别

    方式一:event.stopPropagation(); 方式二:return false; 但是这两种方式是有区别的.return false 不仅阻止了事件往上冒泡,而且阻止了事件本身.event ...

  9. c语言中的经典算法

    c语言经典排序以及查找方法 冒泡排序 #include <stdio.h> int main() { int i, j, t, a[11]; /*定义变量及数组为基本整型*/ printf ...

  10. C#操作AD的例子

    一下连接中包含了使用c#对AD操作的各种列子 http://www.codeproject.com/Articles/18102/Howto-Almost-Everything-In-Active-D ...