自己尝试实现的文件上传功能

今天偶然想自己实现一下文件上传功能,但又不知从何入手,于是打算走一步算一步。

获得request的输入流,将其完全输出,发现里面的内容格式是类似于这样的:

-----------------------------7d81853a1055a
Content-Disposition:form-data;name="first"

FirstPara
-----------------------------7d81853a1055a
Content-Disposition:form-data;name="file";filename="C://DocumentsandSettings//RayChase//桌面//Try.txt"
Content-Type:text/plain

TRY
-----------------------------7d81853a1055a
Content-Disposition:form-data;name="last"

LastPara
-----------------------------7d81853a1055a--

其中的双斜杠应该为单斜杠。这样一来我就有思路了:

文件参数之前有个表单参数first,之后有个表单参数last,而分隔这三者的皆是被我称为“分隔符”的东西,即是那个"-----------------------------7d81853a1055a"这样的内容,那么我想我先获取分隔符,然后从那一串filename="......"中获取文件名Try.txt,并从下面一行的Content-Type的后面获取浏览器认定的文件类型,再跳过一个空行,下面就是文件内容了,接着分隔符则标志着文件内容的结束。由此,我就可以依据解析的文件名建立文件,再将对应的文件内容写入了。

那就来尝试一下吧。后来找了几个算法,都有个问题,就是在输入文件内容后总会多加上一个回车换行符(源于request擅自添加的);而我的实现倒是没有这个问题。

package com.XiongYi.file;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class UploadGroupware extends HttpServlet ... {

/***//**
*ThedoGetmethodoftheservlet.<br>
*
*Thismethodiscalledwhenaformhasitstagvaluemethodequalstoget.
*
*
@paramrequesttherequestsendbytheclienttotheserver
*
@paramresponsetheresponsesendbytheservertotheclient
*
@throwsServletExceptionifanerroroccurred
*
@throwsIOExceptionifanerroroccurred
*/

publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException...{

doPost(request,response);
}


/***//**
*ThedoPostmethodoftheservlet.<br>
*
*Thismethodiscalledwhenaformhasitstagvaluemethodequalstopost.
*
*
@paramrequesttherequestsendbytheclienttotheserver
*
@paramresponsetheresponsesendbytheservertotheclient
*
@throwsServletExceptionifanerroroccurred
*
@throwsIOExceptionifanerroroccurred
*/

publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException...{

System.out.println(request.getParameter(
"first"));
System.out.println(request.getParameter(
"file"));
//jsp页面中加入了enctype="multipart/form-data"
//那么这两句话是没有用的,只能输出null。

ServletInputStreamsis
=request.getInputStream();
bytebuf[]=newbyte[1024];
intnum;
Strings;
Stringtype
=null;

Stringpagination
=null;
//分隔符。比如:-----------------------------7d83152f30556

while((num=sis.readLine(buf,0,buf.length))!=-1)...{
//readLine的第三个参数和read方法的第三个参数不同,
//read方法第三个参数若为-1表示取到流末尾,
//readLine方法则不能这么用。

if(pagination==null)
pagination
=newString(buf,0,num);

s
=newString(buf,0,num,"GBK");
if(s.startsWith("Content-Disposition:"))...{
//可能会出现文件

StringnextS;
//下一行
num=sis.readLine(buf,0,buf.length);
nextS
=newString(buf,0,num,"GBK");

if(!nextS.startsWith("Content-Type:"))
continue;//看来不是文件,继续吧

type
=nextS.substring(nextS.indexOf("")+1);
//读取上传文件类型信息
System.out.println(type);

Stringname
=s.substring(s.lastIndexOf("/")+1,s.length()-3);
//取出名字来
System.out.println(name);

Filefile
=newFile("./upload/"+name);
FileOutputStreamfos
=newFileOutputStream(file);

sis.readLine(buf,
0,buf.length);//跳过空行

bytebuf2[]=newbyte[1024];
//再准备一个相同大小的缓冲数组是为了交替使用,
//以便在发现文件结束时避免输出最末两个字节(回车换行符),
//而这最末的两个字节是request自己加上的!
intnum2=0;

booleanwhichBuf=true;
//确定使用哪个缓冲数组

while(num!=-1&&num2!=-1)...{

if(whichBuf)...{
num
=sis.readLine(buf,0,buf.length);
s
=newString(buf,0,num,"GBK");
if(s.startsWith(pagination))...{
if(num2>=2)
num2
=num2-2;
fos.write(buf2,
0,num2);
num
=-1;//写完了
}
else...{
fos.write(buf2,
0,num2);
}

}
else...{
num2
=sis.readLine(buf2,0,buf2.length);
s
=newString(buf2,0,num2,"GBK");
if(s.startsWith(pagination))...{
if(num>=2)
num
=num-2;
fos.write(buf,
0,num);
num2
=-1;//写完了
}
else...{
fos.write(buf,
0,num);
}


}
//else
whichBuf=!whichBuf;
}
//while

fos.close();

}
//if

}
//while
sis.close();

}
//doPost

}

经试验上传各种类型的文件(包括图片、文本等)都没有问题。

如果有其他或者优化的方法,请不吝赐教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值