当前位置:首页 » 文件管理 » 多文件上传

多文件上传

发布时间: 2022-02-05 20:02:53

‘壹’ 多线程 同时上传多个文件

另起线程上传,通过事件更新界面。

‘贰’ 如何实现多文件上传

可用多个FileUpload,自己可以写一些逻辑
用一个按钮提交,可用foreach取得每个FileUpload,用FileUpload的PostedFile得到每个上传的文件

‘叁’ 如何上传多个文件

含义 ENCTYPE="multipart/form-data" 说明:
通过 http 协议上传文件 rfc1867协议概述,jsp 应用举例,客户端发送内容构造

1、概述在最初的 http 协议中,没有上传文件方面的功能。 rfc1867 (http://www.ietf.org/rfc/rfc1867.txt) 为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。

2、上传文件的实例:用 servelet 实现(http server 为 tomcat 4.1.24)1. 在一个 html 网页中,写一个如下的form :

load multi files :

text field :

用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给 http://192.168.29.65/upload_file/UploadFile

这是一个 servelet 程序注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc18672. 服务端 servelet 的编写现在第三方的 http upload file 工具库很多。Jarkata 项目本身就提供了fileupload 包http://jakarta.apache.org/commons/fileupload/ 。

文件上传、表单项处理、效率问题基本上都考虑到了。在 Struts 中就使用了这个包,不过是用 Struts 的方式另行封装了一次。这里我们直接使用 fileupload 包。至于Struts 中的用法,请参阅 Struts 相关文档。这个处理文件上传的 servelet 主要代码如下:

public void doPost( HttpServletRequest request, HttpServletResponse response )
{
DiskFileUpload diskFileUpload = new DiskFileUpload(); // 允许文件最大长度
diskFileUpload.setSizeMax( 100*1024*1024 ); // 设置内存缓冲大小
diskFileUpload.setSizeThreshold( 4096 ); // 设置临时目录
diskFileUpload.setRepositoryPath( "c:/tmp" );
List fileItems = diskFileUpload.parseRequest( request );
Iterator iter = fileItems.iterator(); for( ; iter.hasNext(); )
{
FileItem fileItem = (FileItem) iter.next();
if( fileItem.isFormField() ) { // 当前是一个表单项
out.println( "form field : " + fileItem.getFieldName() + ", " + fileItem.getString() );
} else {
// 当前是一个上传的文件
String fileName = fileItem.getName();
fileItem.write( new File("c:/uploads/"+fileName) );
}

}}

为简略起见,异常处理,文件重命名等细节没有写出。3、 客户端发送内容构造假设接受文件的网页程序位于 http://192.168.29.65/upload_file/UploadFile.假设我们要发送一个二进制文件、一个文本框表单项、一个密码框表单项。文件名为 E:\s ,其内容如下:(其中的XXX代表二进制数据,如 01 02 03)abbXXXccc 客户端应该向 192.168.29.65 发送如下内容:

POST /upload_file/UploadFile HTTP/1.1
Accept: text/plain, */*
Accept-Language: zh-cn
Host: 192.168.29.65:80
Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6
User-Agent: Mozilla/4.0 (compatible; OpenOffice.org)
Content-Length: 424
Connection: Keep-Alive -----------------------------7d33a816d302b6
Content-Disposition:form-data;
name="userfile1";
filename="E:\s"Content-Type:
application/octet-stream abbXXXccc
-----------------------------7d33a816d302b6

Content-Disposition: form-data;

name="text1" foo

-----------------------------7d33a816d302b6

Content-Disposition: form-data;

name="password1" bar

-----------------------------7d33a816d302b6--

(上面有一个回车)此内容必须一字不差,包括最后的回车。

注意:Content-Length: 424 这里的424是红色内容的总长度(包括最后的回车)
注意这一行:Content-Type: multipart/form-data; boundary=---------------------------7d33a816d302b6

根据 rfc1867, multipart/form-data是必须的.---------------------------7d33a816d302b6 是分隔符,分隔多个文件、表单项。

其中33a816d302b6 是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。前面的 ---------------------------7d 是 IE 特有的标志。

Mozila 为---------------------------71用手工发送这个例子,在上述的 servlet 中检验通过。

使用POST发送数据

以POST方式发送数据主要是为了向服务器发送较大量的客户端的数据,它不受URL的长度限制。POST请求将数据以URL编码的形式放在HTTP正文中,字段形式为fieldname=value,用&分隔每个字段。注意所有的字段都被作为字符串处理。实际上我们要做的就是模拟浏览器POST一个表单。以下是IE发送一个登陆表单的POST请求:

POST http://127.0.0.1/login.do HTTP/1.0
Accept: image/gif, image/jpeg, image/pjpeg, */*
Accept-Language: en-us,zh-cn;q=0.5
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Content-Length: 28
\r\n
username=admin&password=1234

要在MIDP应用程序中模拟浏览器发送这个POST请求,首先设置HttpConnection的请求方式为POST:

hc.setRequestMethod(HttpConnection.POST);

然后构造出HTTP正文:

byte[] data = "username=admin&password=1234".getBytes();

并计算正文长度,填入Content-Type和Content-Length:

hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
hc.setRequestProperty("Content-Length", String.valueOf(data.length));

然后打开OutputStream将正文写入:

OutputStream output = hc.openOutputStream();
output.write(data);

需要注意的是,数据仍需要以URL编码格式编码,由于MIDP库中没有J2SE中与之对应的URLEncoder类,因此,需要自己动手编写这个encode()方法,可以参考java.net.URLEncoder.java的源码。剩下的便是读取服务器响应,代码与GET一致,这里就不再详述。

使用multipart/form-data发送文件

如果要在MIDP客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求,Content-Type必须是multipart/form-data。

以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同,multipart/form-data需要首先在HTTP请求头设置一个分隔符,例如ABCD:

hc.setRequestProperty("Content-Type", "multipart/form-data; boundary=ABCD");

然后,将每个字段用“--分隔符”分隔,最后一个“--分隔符--”表示结束。例如,要上传一个title字段"Today"和一个文件C:\1.txt,HTTP正文如下:

--ABCD
Content-Disposition: form-data; name="title"
\r\n
Today
--ABCD
Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt"
Content-Type: text/plain
\r\n

--ABCD--
\r\n

请注意,每一行都必须以\r\n结束,包括最后一行。如果用Sniffer程序检测IE发送的POST请求,可以发现IE的分隔符类似于---------------------------7d4a6d158c9,这是IE产生的一个随机数,目的是防止上传文件中出现分隔符导致服务器无法正确识别文件起始位置。我们可以写一个固定的分隔符,只要足够复杂即可。

发送文件的POST代码如下:

String[] props = ... // 字段名
String[] values = ... // 字段值
byte[] file = ... // 文件内容
String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔符
StringBuffer sb = new StringBuffer();
// 发送每个字段:
for(int i=0; i
sb = sb.append("--");
sb = sb.append(BOUNDARY);
sb = sb.append("\r\n");
sb = sb.append("Content-Disposition: form-data; name=\""+ props[i] + "\"\r\n\r\n");
sb = sb.append(URLEncoder.encode(values[i]));
sb = sb.append("\r\n");
}
// 发送文件:
sb = sb.append("--");
sb = sb.append(BOUNDARY);
sb = sb.append("\r\n");
sb = sb.append("Content-Disposition: form-data; name=\"1\"; filename=\"1.txt\"\r\n");
sb = sb.append("Content-Type: application/octet-stream\r\n\r\n");
byte[] data = sb.toString().getBytes();
byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
// 设置HTTP头:
hc.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
hc.setRequestProperty("Content-Length", String.valueOf(data.length + file.length + end_data.length));
// 输出:
output = hc.openOutputStream();
output.write(data);
output.write(file);
output.write(end_data);
// 读取服务器响应:
// TODO...

‘肆’ 多文件上传思路

大概看了一下的代码,这个程序应该是 Web Form 的程序吧?

如果是这样的话,你可以 javascript 的方式来实现啊。比如开始页面上只有一个 <input type="file" name="uploader" />。旁边加一个按钮或者链接什么的,当被点击的时候调用客户端脚本添加一个新的 <input type="file" name="uploader" /> 元素。这样就可以同时上传多个文件了哦

然后在服务器端可以调用 Page.Request.Files 获取刚上传的文件

==================================

在 .NET 中,FileUpload 控件最后都会被转化成HTML中的 <input type="text" /> 元素。而这个 HTML 元素是只能一次上传一个文件的。

你如果要一次上传几个文件:
1. 用脚本生成多个 <input type="text" /> HTML 元素
2. 如果只使用一个 FileUpload 控件,那么点上传的时候可以将文件暂时保存在服务器的内存中。这样 FileUpload 就又可以继续上传新的文件了

‘伍’ 如何用Ajax实现多文件上传

jquery 实现多个上传文件教程:
首先创建解决方案,添加jquery的js和一些资源文件(如图片和进度条显示等):
1
2
3
4
5
jquery-1.3.2.min.js
jquery.uploadify.v2.1.0.js
jquery.uploadify.v2.1.0.min.js
swfobject.js
uploadify.css
1、页面的基本代码如下
这里用的是aspx页面(html也是也可的)
页面中引入的js和js函数如下:
1
2
3
4
5
6
7
<script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="js/jquery.uploadify.v2.1.0.js" type="text/javascript"></script>
<script src="js/jquery.uploadify.v2.1.0.min.js" type="text/javascript"></script>
<script src="js/swfobject.js" type="text/javascript"></script>
<link href="css/uploadify.css" rel="stylesheet" type="text/css" />

</script>
js函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script type="text/javascript">
$(document).ready(function () {

$("#uploadify").uploadify({
'uploader': 'image/uploadify.swf', //uploadify.swf文件的相对路径,该swf文件是一个带有文字BROWSE的按钮,点击后淡出打开文件对话框
'script': 'Handler1.ashx',// script : 后台处理程序的相对路径
'cancelImg': 'image/cancel.png',
'buttenText': '请选择文件',//浏览按钮的文本,默认值:BROWSE。
'sizeLimit':999999999,//文件大小显示
'floder': 'Uploader',//上传文件存放的目录
'queueID': 'fileQueue',//文件队列的ID,该ID与存放文件队列的div的ID一致
'queueSizeLimit': 120,//上传文件个数限制
'progressData': 'speed',//上传速度显示
'auto': false,//是否自动上传
'multi': true,//是否多文件上传
//'onSelect': function (e, queueId, fileObj) {
// alert("唯一标识:" + queueId + "\r\n" +
// "文件名:" + fileObj.name + "\r\n" +
// "文件大小:" + fileObj.size + "\r\n" +
// "创建时间:" + fileObj.creationDate + "\r\n" +
// "最后修改时间:" + fileObj.modificationDate + "\r\n" +
// "文件类型:" + fileObj.type);

// }
'onQueueComplete': function (queueData) {
alert("文件上传成功!");
return;
}

});
});
页面中的控件代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<form id="form1" runat="server">
<div id="fileQueue">
</div>
<div>
<p>
<input type="file" name="uploadify" id="uploadify"/>
<input id="Button1" type="button" value="上传" onclick="javascript: $('#uploadify').uploadifyUpload()" />
<input id="Button2" type="button" value="取消" onclick="javascript:$('#uploadify').uploadifyClearQueue()" />
</p>
</div>
</form>
</body>
函数主要参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$(document).ready(function() {
$('#fileInput1').fileUpload({
'uploader': 'uploader.swf',//不多讲了
'script': '/AjaxByJQuery/file.do',//处理Action
'cancelImg': 'cancel.png',
'folder': '',//服务端默认保存路径
'scriptData':{'methed':'uploadFile','arg1','value1'},
//向后台传递参数,methed,arg1为参数名,uploadFile,value1为对应的参数值,服务端通过request["arg1"]
'buttonText':'UpLoadFile',//按钮显示文字,不支持中文,解决方案见下
//'buttonImg':'图片路径',//通过设置背景图片解决中文问题,就是把背景图做成按钮的样子
'multi':'true',//多文件上传开关
'fileExt':'*.xls;*.csv',//文件过滤器
'fileDesc':'.xls',//文件过滤器 详解见文档
'onComplete' : function(event,queueID,file,serverData,data){
//serverData为服务器端返回的字符串值
alert(serverData);
}
});
});
后台一般处理文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Web;
using System.Web.Services;
namespace fupload
{
/// <summary>
/// Handler1 的摘要说明
/// </summary>
public class Handler1 : IHttpHandler
{

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";

HttpPostedFile file = context.Request.Files["Filedata"];//对客户端文件的访问

string uploadPath = HttpContext.Current.Server.MapPath(@context.Request["folder"])+"\\";//服务器端文件保存路径

if (file != null)
{
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);//创建服务端文件夹
}

file.SaveAs(uploadPath + file.FileName);//保存文件
context.Response.Write("上传成功");
}

else
{
context.Response.Write("0");
}

}

public bool IsReusable
{
get
{
return false;
}
}
}
}
以上方式基本可以实现多文件的上传,大文件大小是在控制在10M以下/。

‘陆’ html有关多个文件上传

//改好了没问题..加文件试试
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<script type="text/javascript">

function imgChange(next) {
if(next != null)
document.getElementById(next).style.display = "";
}

function validate() {
var phos = 2;
for(i = 0; i < 2; i++) {
if($("del" + i).checked == true)
phos--;
}
for(i = 0; i < 4; i++) {
if($("photoFile" + i).value != "")
phos++;
}
if(phos > 4) {
alert("图片太多,您最多总共可以保存4张图片!");
return false;
}
return true;
}
</script>

<form action="/addTrade.do" method="post" enctype="multipart/form-data" onSubmit="return validate()">
<!-- 上传照片-->
<div>

<table width="100%" border="0" cellspacing="0" cellpadding="0"
summary="upload pictures">
<tr id="tr_photoFile0">
<td width="119" align="right" class="title">
上传照片:
</td>

<td width="499">
<input type="file" name="photoFile0" id="photoFile0"
size="40" onChange='return imgChange("tr_photoFile1")' />
</td>
</tr>
<tr id="tr_photoFile1" style="display: none;">
<td>

</td>
<td>

<input type="file" name="photoFile1" id="photoFile1"
onChange='return imgChange("tr_photoFile2")' size="40" />
</td>
</tr>
<tr id="tr_photoFile2" style="display: none;">
<td>

</td>
<td>
<input type="file" name="photoFile2" id="photoFile2"
onChange='return imgChange("tr_photoFile3")' size="40" />

</td>
</tr>
<tr id="tr_photoFile3" style="display: none;">
<td>

</td>
<td>
<input type="file" name="photoFile3" id="photoFile3"
onChange='return imgChange(null)' size="40" />
</td>

</tr>
</table>
</div>

<!--/ 上传照片-->
<input name="submit" type="submit" value="提交"/>
</form>

热点内容
饥荒搭建服务器有宝箱吗 发布:2024-10-23 01:42:08 浏览:589
五指速算法 发布:2024-10-23 01:41:58 浏览:116
360修复蓝屏上传失败 发布:2024-10-23 01:33:01 浏览:921
c语言二级程序设计题 发布:2024-10-23 01:17:52 浏览:497
哪个安卓浏览器能搜到更多影视 发布:2024-10-23 01:10:16 浏览:895
oppor9怎么升级安卓70 发布:2024-10-23 01:09:26 浏览:515
上网闸ftp端口 发布:2024-10-23 00:54:55 浏览:429
手游脚本编辑 发布:2024-10-23 00:51:00 浏览:276
java可以做游戏脚本吗 发布:2024-10-23 00:49:32 浏览:501
大公报数据库 发布:2024-10-23 00:46:52 浏览:251