php实现断点下载
HTTP断点续传原理
Http头 Range、Content-Range()
HTTP头中一般断点下载时才用到Range和Content-Range实体头,
Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300)
Content-Range用于响应头
请求下载整个文件:
GET /test.rar HTTP/1.1
Connection: close
Host: 116.1.219.219
Range: bytes=0-801 //一般请求下载整个文件是bytes=0- 或不用这个头
一般正常回应
HTTP/1.1 200 OK
Content-Length: 801
Content-Type: application/octet-stream
Content-Range: bytes 0-800/801 //801:文件总大小
<?php
/** php下载类,支持断点续传
* Date: 2014-05-15
* Author: 郝翔
* Ver: 1.0
*
* Func:
* download: 下载文件
* setSpeed: 设置下载速度
* getRange: 获取header中Range
*/
class FileDownload{ // class start
private $_speed = 512; // 下载速度 /** 下载
* @param String $file 要下载的文件路径
* @param String $name 文件名称,为空则与下载的文件名称一样
* @param boolean $reload 是否开启断点续传
*/
public function download($file, $name='', $reload=false){
ob_start();
$file=iconv('UTF-8','GB2312',$file); //否则不能判断中文的文件名
if(file_exists($file)){
if($name==''){
$name = basename($file);
}
$fp = fopen($file, 'rb');
$file_size = filesize($file);
$ranges = $this->getRange($file_size); header('cache-control:public');
header('content-type:application/octet-stream');
header('content-disposition:attachment; filename='.$name); if($reload && $ranges!=null){ // 使用续传
header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges:bytes');
// 剩余长度
header(sprintf('content-length:%u',$ranges['end']-$ranges['start']));
// range信息
header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
// fp指针跳到断点位置
fseek($fp, sprintf('%u', $ranges['start']));
}else{
header('HTTP/1.1 200 OK');
header('content-length:'.$file_size);
}
while(!feof($fp)){
set_time_limit(0); //设置脚本最大执行时间 0 表示没有限制
echo fread($fp, round($this->_speed*1024,0)); //读取文件(可安全用于二进制文件),从文件指针 handle 读取最多 length 个字节
flush();//该函数将当前为止程序的所有输出发送到用户的浏览器。
ob_flush();//flush() 函数不会对服务器或客户端浏览器的缓存模式产生影响。因此,必须同时使用 ob_flush()
}
($fp!=null) && fclose($fp);
}else{
return '';
}
}
/** 设置下载速度
* @param int $speed
*/
public function setSpeed($speed){
if(is_numeric($speed) && $speed>16 && $speed<4096){
$this->_speed = $speed;
}
}
/** 获取header range信息
* @param int $file_size 文件大小
* @return Array
*/
private function getRange($file_size){
if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])){
$range = $_SERVER['HTTP_RANGE'];
$range = preg_replace('/[\s|,].*/', '', $range);
$range = explode('-', substr($range, 6));
if(count($range)<2){
$range[1] = $file_size;
}
$range = array_combine(array('start','end'), $range);
if(empty($range['start'])){
$range['start'] = 0;
}
if(empty($range['end'])){
$range['end'] = $file_size;
}
return $range;
}
return null;
} } // class end ?>
测试使用:
使用linux wget命令去测试下载, wget -c -O file http://xxx
下载的文件默认保存在当前文件夹下
如何使用:
<body>
<h1>
<a href="demo.php">断点续传测试</a>
</h1>
</body>
<?php
require('FileDownload.class.php');
$file = 'book.zip';
$name = time().'.zip';
$obj = new FileDownload();
$flag = $obj->download($file, $name);
//$flag = $obj->download($file, $name, true); // 断点续传 if(!$flag){
echo 'file not exists';
} ?>
php实现断点下载的更多相关文章
- Java实现多线程断点下载(下载过程中可以暂停)
线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...
- 安卓(android)之实现断点下载功能
一.建立实体类 1.文件实体类 package com.example.zjw.myapplication.dao; import java.io.Serializable; /** * 预下载文件实 ...
- iOS 大文件断点下载
iOS 在下载大文件的时候,可能会因为网络或者人为等原因,使得下载中断,那么如何能够进行断点下载呢? // resumeData的文件路径 #define XMGResumeDataFile [[NS ...
- 【Java EE 学习 22 下】【单线程下载】【单线程断点下载】【多线程下载】
一.文件下载简述 1.使用浏览器从网页上下载文件,Servlet需要增加一些响应头信息 (1)response.setContentType("application/force-downl ...
- IOS 断点下载
// // ViewController.m // UI4_断点下载 // // Created by qianfeng on 15/8/19. // Copyright (c) 2015年 ZBC. ...
- .net网站的文件上传读取进度条和断点下载
文件上传到服务器时的进度读取 //调整上传配置 AdapterInfo(info); UpfileResult result = new UpfileResult(); try { //直接使用req ...
- iOS开发——网络篇——NSURLSession,下载、上传代理方法,利用NSURLSession断点下载,AFN基本使用,网络检测,NSURLConnection补充
一.NSURLConnection补充 前面提到的NSURLConnection有些知识点需要补充 NSURLConnectionDataDelegate的代理方法有一下几个 - (void)conn ...
- unity3d 关于断点下载和整个下载(用于更新)
转自:http://blog.csdn.net/yutyliu/article/details/24346459 string t = ""; //整体下载 IEnumerator ...
- iOS开发网络篇—大文件的多线程断点下载
http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...
- iOS开发网络请求——大文件的多线程断点下载
iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...
随机推荐
- 总结自己的Git常用命令
总结自己的Git常用命令 使用git也有一段时间了,把自己常用的命令用自己的描述记录起来,方便自己备忘也方便其他人参考. 目录: 最基本的命令: git clone 拷贝并跟踪远程的master分支. ...
- C/C++ strtok函数
一.头文件:#include <string.h> 二.函数原型:char * strtok (char *str, const char * delimiters); 三.参数:str, ...
- HDU 1887 Weird Numbers(负数的进制转化)
题目要求有两种情况,第一种from情况,正常输出即可,很简单.第二种是to情况,给一个数字,输出负进制R的原码,这个有点小麻烦...解决方法如下; 首先,把这个数n按正常方式展开,形式如下: .... ...
- HRBUST 1909 理工门外的树(双数组实现线段树功能)
线段树固然可以做,但是在考虑线段树之前应该先考虑一下,这种用两个数组来解决问题的方法能不能行,如果行的话,就会为我们省很多时间,毕竟线段树代码量比较大 #include<iostream> ...
- Hadoop的初步理解
一.整体思维导图 二.HDFS(Hadoop分布式文件系统) 说明 NameNode:保存整个文件系统的目录信息.文件信息及分块信息,这是由唯一一台主机专门保存,当然这台主机如果出错,NameNode ...
- Struts2--DomainModel接收参数---使用广泛!!!
1. JSP文件调用格式: <a href="user/user!add?user.name=a&user.age=8">添加用户</a> 2. s ...
- Android4.2以后,多屏幕的支持 学习(一)
前几天总结了Android的多用户支持,过几天准备再总结Android的多屏支持.Android支持3种类型屏幕:主屏幕(Primary Display).外屏幕(External Display)和 ...
- 第十七篇 --ANDROID DisplayManager 服务解析一
ANDROID从版本4.2开始提供了一个显示管理服务DisplayManagerService,支持多种显示类型的多个显示器的镜像显示,包括内建的显示类型(本地).HDMI显示类型以及支持WIFI D ...
- javascript中0.01*2324=23.240000000000002 ?
js中的乘法运算的小问题 0.01*2324=23.240000000000002 ? , 结果为什么出现这么多小数位呢?
- [Big Data]hadoop分布式系统在Linux系统安装
待完善 Hadoop2.6.0部署与应用 一. 环境准备 硬件:3台虚拟机 内存:至少512MB 硬盘:至少20G 操作系统:rhel6.4 64位 最小化安装 主机名 IP(局域网) 描述 ...