文件的上传在本地来说就是把一个文件挪到另一个地方,对于网络来说只是目标地址是网络的地址而已。java实现的原理代码如下:
File source =new File("F:/music/一生爱你千百回.mp3");
//定义目标路径
File target =new File("D:/music",source.getName());
//开始上传
CopyFile(source,target);
//实现文件上传的核心代码
static void CopyFile (File source ,File target){
InputStream in=null;
OutputStream out=null;
in=new FileInputStream(source);
out=new FileOutputStream(target);
byte[] buf =new byte[1024*10];
int len=in.read(buf);
while(len!=-1){
out.write(buf,0,len);
len=in.read(buf);
}
}
============================================================================
下面就是手工写的一个servlet上传的一个例子:
1:控制层的代码:ServletActon.jsp
package com.test.action;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.Hashtable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletAction extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
final int NONE=0;
final int DATAHEADER=1;
final int FILEDATA=2;
final int FIELDDATA=3;
//将请求消息的实体送到b变量中
int TotalBytes=request.getContentLength();
byte[] b=new byte[TotalBytes];
String contentType=request.getContentType();//请求消息类型
String fieldname=""; //表单域的名称
String fieldvalue=""; //表单域的值
String filename=""; //文件名
String boundary=""; //分界符
String lastboundary=""; //结束符
int filesize=0; //文件长度
Hashtable formfields=new Hashtable();
int pos=contentType.indexOf("boundary=");
String fileID; //上传的文件ID
if(pos!=-1) //取得分界符和结束符
{
pos+="boundary=".length();
boundary="--"+contentType.substring(pos);
lastboundary=boundary+"--";
}
int state=NONE;
//得到数据输入流reqbuf
DataInputStream in=new DataInputStream(request.getInputStream());
in.readFully(b);
in.close();
String reqContent=new String(b);
BufferedReader reqbuf=new BufferedReader(new StringReader(reqContent));
boolean flag=true;
int i=0;
while(flag==true)
{
String s=reqbuf.readLine();
if((s==lastboundary)||(s==null)) break;
switch(state)
{
case NONE:
if (s.startsWith(boundary))
{
state=DATAHEADER;
i+=1;
}
break;
case DATAHEADER:
pos=s.indexOf("filename=");
if (pos==-1)
{ //将表单域的名字解析出来
pos=s.indexOf("name=");
pos+="name=".length()+1;
s=s.substring(pos);
int l=s.length();
s=s.substring(0,l-1);
fieldname=s;
state=FIELDDATA;
}
else
{ //将文件名解析出来
String temp=s;
pos=s.indexOf("filename=");
pos+="filename=".length()+1;
s=s.substring(pos);
int l=s.length();
s=s.substring(0,l-1);
pos=s.lastIndexOf("\\");
s=s.substring(pos+1);
filename=s;
//从字节数组中取出文件数组
pos=byteIndexOf(b,temp,0);
b=subBytes(b,pos+temp.getBytes().length+2,b.length);//去掉前面的部分
s=reqbuf.readLine();
b=subBytes(b,s.getBytes().length+4,b.length);
pos=byteIndexOf(b,boundary,0);
b=subBytes(b,0,pos-1);
File f=new File(formfields.get("FilePath")+"\\"+filename); //写入文件
DataOutputStream fileout=new DataOutputStream(new FileOutputStream(f));
fileout.write(b,0,b.length-1);
filesize=b.length-1;
state=FILEDATA;
}
break;
case FIELDDATA:
s=reqbuf.readLine();
fieldvalue=s;
formfields.put(fieldname,fieldvalue);
state=NONE;
break;
case FILEDATA:
while((!s.startsWith(boundary))&&(!s.startsWith(lastboundary)))
{
s=reqbuf.readLine();
if (s.startsWith(boundary))
{
state=DATAHEADER;
break;
}
}
break;
}
}
//指定输出类型
response.setContentType("text/html;charset=gb2312");
PrintWriter out =response.getWriter();
out.println("<html>");
out.println("<head><title>文件上传结果</title></head>");
out.println("<body>");
out.println("<h1>文件上传结果</h1><hr>");
out.println("ID为"+formfields.get("FileID")+"的文件"+filename+"已经上传!"+
"文件长度为:"+filesize+"字节");
out.println("</body></html>");
out.close();
}
//Get Servlet information
public String getServletInfo() {
return "UploadServlet.UploadServlet Information";
}
//字节数组中的INDEXOF函数,与STRING类中的INDEXOF类似
private static int byteIndexOf(byte[] b,String s,int start)
{
return byteIndexOf(b,s.getBytes(),start);
}
//字节数组中的INDEXOF函数,与STRING类中的INDEXOF类似
private static int byteIndexOf(byte[] b,byte[] s,int start)
{
int i;
if(s.length==0)
{
return 0;
}
int max=b.length-s.length;
if(max<0)
return -1;
if(start>max)
return -1;
if (start<0)
start=0;
search:
for(i=start;i<=max;i++)
{
if (b[i]==s[0])
{
int k=1;
while(k<s.length)
{
if(b[k+i]!=s[k])
{
continue search;
}
k++;
}
return i;
}
}
return -1;
}
//用于从一个字节数组中提取一个字节数组
private static byte[] subBytes(byte[] b,int from,int end)
{
byte[] result=new byte[end-from];
System.arraycopy(b,from,result,0,end-from);
return result;
}
//用于从一个字节数组中提取一个字符串
private static String subBytesString(byte[] b,int from,int end)
{
return new String(subBytes(b,from,end));
}
}
2:客户端的代码 index.html
<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上传文件</title>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse"
bordercolor="#111111" width="100%" id="AutoNumber1">
<tr>
<td width="15%"> </td>
<td width="80%">
<table border="0" cellpadding="10" cellspacing="10" style="border-collapse: collapse"
bordercolor="#111111" width="100%" id="AutoNumber5">
<tr>
<td width="100%"><b><font face="黑体">全文辅助工具之一:上传文件接收</font></b></td>
</tr>
<tr>
<td width="100%">
<p align="right"><font color="#FF0000" size="2">作者:qixiaorui</font></td>
</tr>
</table>
</td>
<td width="5%"> </td>
</tr>
<tr>
<td width="15%"> </td>
<td width="80%">
<table border="1" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"
width="100%" id="AutoNumber2">
<tr>
<td width="100%">
<form method="POST" enctype="multipart/form-data" action="http://localhost:8080/UpAndDownTest/upload">
<table border="0" cellpadding="10" cellspacing="10" style="border-collapse: collapse"
bordercolor="#111111" width="100%" id="AutoNumber3">
<tr>
<td width="100%" bgcolor="#00FFFF">
<p align="center"><font face="华文仿宋" color="#000080"><b>
--------------------------------- 上 传 文 件
----------------------------------</b></font></td>
</tr>
<tr>
<td width="100%">
<table border="0" cellpadding="3" cellspacing="3" style="border-collapse: collapse"
bordercolor="#111111" width="100%" id="AutoNumber4">
<tr>
<td width="27%">请输入服务器路径:</td>
<td width="73%"><input type="text" name="FilePath" size="52">
如: c:\aa</td>
</tr>
<tr>
<td width="27%">请输入操作ID:</td>
<td width="73%"><input type="text" name="FileID" size="52"></td>
</tr>
<tr>
<td width="27%">请输入文件路径:</td>
<td width="73%"><input type="file" name="FileData" size="41"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td width="100%">
<input type="submit" value="提交" name="uploadfile">
<input type="reset" value="重置" name="B2"></td>
</tr>
</table>
</form>
</td>
</tr>
</table>
</td>
<td width="5%"> </td>
</tr>
<tr>
<td width="15%"> </td>
<td width="80%"> </td>
<td width="5%"> </td>
</tr>
</table>
</body>
</html>
3:配置端代码:web.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<web-app id="IDOLSearch">
<display-name>test</display-name>
<description>This is Idol Sever Default Web Application.</description>
<servlet>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>com.test.action.ServletAction</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/upload/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
=============================================================
对于web应用的一些下载可以用一些现成的插件,例如common-fileupload组件
下载地址:http://jakarta.apache.org/commons /fileupload/import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.fileupload.*;
public class Upload extends HttpServlet {
private String uploadPath = "C:\\upload\\"; // 用于存放上传文件的目录
private String tempPath = "C:\\upload\\tmp\\"; // 用于存放临时文件的目录
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
try {
DiskFileUpload fu = new DiskFileUpload();
// 设置最大文件尺寸,这里是4MB
fu.setSizeMax(4194304);
// 设置缓冲区大小,这里是4kb
fu.setSizeThreshold(4096);
// 设置临时目录:
fu.setRepositoryPath(tempPath);
// 得到所有的文件:
List fileItems = fu.parseRequest(request);
Iterator i = fileItems.iterator();
// 依次处理每一个文件:
while(i.hasNext()) {
FileItem fi = (FileItem)i.next();
// 获得文件名,这个文件名包括路径:
String fileName = fi.getName();
if(fileName!=null) {
// 在这里可以记录用户和文件信息
// ...
// 写入文件a.txt,你也可以从fileName中提取文件名:
fi.write(new File(uploadPath + "a.txt"));
}
}
// 跳转到上传成功提示页面
}
catch(Exception e) {
// 可以跳转出错页面
}
}
}
//当servlet收到浏览器发出的Post请求后,在doPost()方法中实现文件上传。以下是示例代码:
如果要在配置文件中读取指定的上传文件夹,可以在init()方法中执行:
public void init() throws ServletException {
uploadPath = ....
tempPath = ....
// 文件夹不存在就自动创建:
if(!new File(uploadPath).isDirectory())
new File(uploadPath).mkdirs();
if(!new File(tempPath).isDirectory())
new File(tempPath).mkdirs();
}
配置servlet,用记事本打开tomcat\webapps\你的webapp\WEB-INF\web.xml,没有的话新建一个。典型配置如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>Upload</servlet-name>
<servlet-class>Upload</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Upload</servlet-name>
<url-pattern>/fileupload</url-pattern>
</servlet-mapping>
</web-app>
配置好servlet后,启动tomcat,写一个简单的html测试:
<form action="fileupload" method="post" enctype="multipart/form-data" name="form1">
<input type="file" name="file">
<input type="submit" name="Submit" value="upload">
</form>
注意action="fileupload"其中fileupload是配置servlet时指定的url-pattern。
================================================================
还有如:commons-fileupload-1.2.1.jar
try {
DiskFileItemFactory dfif=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(dfif);
upload.setSizeMax(10*1024*1024);
List list=upload.parseRequest(request);
for(int i=0;i<list.size();i++){
FileItem item=(FileItem) list.get(i);
String name=item.getName();
String path=this.getServletContext().getRealPath("/upload");
item.write(new File(path,name));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}