大文件上传的实现

时间:2021-07-23 17:23:04

大文件上传的实现

1、大文件上传的基本思路

通过页面实现大文件上传的功能,分为前端页面与后端逻辑。
(1) 前端页面:推荐采用前端上传组件Plupload来实现
(2) 后端逻辑: 可以采用PHP或者CGI的方式

2、前端页面: 采用组件Plupload
(1) Plupload有以下功能和特点: 
a. 拥有多种上传方式:HTML5、flash、silverlight以及传统的<input type=”file” />。Plupload会自动侦测当前的环境,选择最合适的上传方式,并且会优先使用HTML5的方式。所以你完全不用去操心当前的浏览器支持哪些上传方式,Plupload会自动为你选择最合适的方式。
b. 支持以拖拽的方式来选取要上传的文件。
c. 支持在前端压缩图片,即在图片文件还未上传之前就对它进行压缩。
d. 可以直接读取原生的文件数据,这样的好处就是例如可以在图片文件还未上传之前就能把它显示在页面上预览。
e. 支持把大文件切割成小片进行上传,因为有些浏览器对很大的文件比如几GB的一些文件无法上传。
(2) Plupload的使用方法
a. 引入js文件,plupload的源文件可以到github上去下载。https://github.com/moxiecode/plupload
b. 实例化一个plupload对象,传入一个配置参数对象进行各方面的配置。
c. 调用plupload实例对象的init()方法进行初始化。
d. 在plupload实例对象上注册各种你需要的事件。plupload从选取文件到文件上传完成这个过程中,会触发很多事件。我们可以通过这些事件来跟plupload进行交互。
e. 实现你自己所注册的那些事件的监听函数,利用这些监听函数来进行更新UI、提示上传进度等工作。

(3) 提供demo.html代码如下: 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Plupload使用指南</title>
<!-- 首先需要引入plupload的源代码 -->
<script src="js/plupload.full.min.js"></script>
</head>
<body>
<!-- 这里我们只使用最基本的html结构:一个选择文件的按钮,一个开始上传文件的按钮(甚至该按钮也可以不要) -->
<p>
<button id="browse">选择文件</button>
<button id="start_upload">开始上传</button>
</p>
<script>


//实例化一个plupload上传对象
var uploader = new plupload.Uploader({
browse_button : 'browse', //触发文件选择对话框的按钮,为哪个元素id
url : 'upload.php', //服务器端接收上传数据的文件
flash_swf_url : 'js/Moxie.swf', //swf文件,当需要使用swf方式进行上传时需要配置该参数
silverlight_xap_url : 'js/Moxie.xap' //silverlight文件,当需要使用silverlight方式进行上传时需要配置该参数
});


//在实例对象上调用init()方法进行初始化
uploader.init();


//绑定事件
uploader.bind('FilesAdded',function(uploader,files){
// 绑定添加上传文件的事件
});
uploader.bind('UploadProgress',function(uploader,file){
// 绑定上传文件进度的事件
});


//最后给"开始上传"按钮注册事件
document.getElementById('start_upload').onclick = function(){
uploader.start(); //调用实例对象的start()方法开始上传文件,当然你也可以在其他地方调用该方法
}
</script>
</body>
</html>

(4) 使用Plupload的关键是了解它众多的配置参数、事件以及属性和方法。
a. 参考资料: http://www.cnblogs.com/2050/p/3913184.html
b. 备注说明: 该参考资料非常详细的介绍了plupload组件的使用方法。

3、后端逻辑
(1) 后端逻辑有两种实现方案:PHP 或 CGI 
a. PHP实现方案的评估:
a1. 代码实现比较简单。
a2. 必须设置php.ini如下配置参数:
file_uploads: 如果值为on,说明服务器支持文件上传;如果为off,则不支持。
upload_tmp_dir: 设置上传文件临时目录,必须考虑大文件占用的空间。
upload_max_filesize: 服务器允许上传的文件的最大值,以MB为单位。
max_execution_time: PHP中一个指令所能执行的最长时间,单位为秒。
memory_limit: PHP中一个指令所分配的内存空间,单位是MB。
a3. 该方案受到指令执行时间及所占用内存的限制,而大文件上传过程,执行时间较长,占用内存较大,从而会影响执行效率。
a4. 通过以上分析,不推荐采用PHP方案。
b. CGI实现方案的评估: 
b1. 实现过程相对比较复杂。
b2. 不受执行时间及内存的限制,大文件上传的执行效率更高。
b3. 通过以上分析,推荐采用CGI方案。
(2) CGI实现方案的主要流程 [ 推荐采用C语言来实现,考虑使用支持64位的函数或操作 ]
a. 获取http request中如下参数的值: Content-Length boundary name filepath。 
b. 使用函数open64()在服务器上打开一个文件:考虑到必须支持大于2GB的文件,必须使用64bit的函数。
c. 分段将上传文件的数据写入在服务器打开的文件中:实现文件的上传。
d. 重复文件重命名: 相同目录下的相同文件名,默认自动将其重命名为filename(i).format,例如:demo.jpg,重命名为demo(1).jpg 
e. 错误处理,添加debug的log信息到指定的log文件中。