这段时间尝试写了一个小web项目,其中涉及到文件上传与下载,虽然网上有很多成熟的框架供使用,但为了学习我还是选择了自己编写相关的代码。当中遇到了很多问题,所以在此这分享完整的上传与下载代码供大家借鉴。

首先是上传的Servlet代码

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.util.Random; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class UpLoad extends HttpServlet {
private static final long serialVersionUID = 1L; private static final Random RANDOM = new Random();
private String tempFileFolder; //临时文件存放目录
private String fileFolder; //存文件的目录 public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//step 1 将上传文件流写入到临时文件
File tempFile = getTempFile();
writeToTempFile(request.getInputStream(), tempFile); //step 2从临时文件中取得上传文件流
RandomAccessFile randomFile = new RandomAccessFile(tempFile, "r"); //step 3取得文件名称
String filename = getFileName(randomFile); //step 4检查存放文件的目录在不在
checkFold(); //step 5保存文件
long fileSize = saveFile(randomFile, filename); //step 6关闭流对像,删除临时文件
randomFile.close();
tempFile.delete(); } public void init() throws ServletException {
//获取项目所在目录
String contentPath = getServletContext().getRealPath("/");
this.tempFileFolder = contentPath + "files/_tmp";
this.fileFolder = contentPath+"files/_file";
} /**
* 对字符串进行转码
* @param str
* @return 转码后的字符串
*/
private String codeString(String str) {
String s = str;
try {
byte[] temp = s.getBytes("ISO-8859-1");
s = new String(temp, "UTF-8");
return s;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return s;
}
} /**
* 产生临时文件对象
* 会检查临时目录是否存在,如果不存在将创建目录
* @return 临时文件对象
* @throws IOException
*/
private File getTempFile()throws IOException{
File tempFolder = new File(this.tempFileFolder);
if (!tempFolder.exists()){
tempFolder.mkdirs();
}
String tempFileName = this.tempFileFolder+File.separator+Math.abs(RANDOM.nextInt());
File tempFile = new File(tempFileName);
if (!tempFile.exists()){
tempFile.createNewFile();
}
return tempFile;
} /**
* 将上传的数据流存入临时文件
* @param fileSourcel 上传流
* @param tempFile 临时文件
* @throws IOException
*/
private void writeToTempFile(InputStream fileSourcel,File tempFile)throws IOException{
FileOutputStream outputStream = new FileOutputStream(tempFile);
byte b[] = new byte[1000];
int n ;
while ((n=fileSourcel.read(b))!=-1){
outputStream.write(b,0,n);
}
outputStream.close();
fileSourcel.close();
} /**
* 从临时文件流中提取文件名称
* @param randomFile
* @return 解析的文件名称
* @throws IOException
*/
private String getFileName(RandomAccessFile randomFile)throws IOException{
String _line;
while((_line=randomFile.readLine())!=null && !_line.contains("form-data; name=\"upload\"")){
}
String filePath = _line;
String filename = filePath.replace("Content-Disposition: form-data; name=\"upload\"; filename=\"", "").replace("\"",""); filename=codeString(filename);
randomFile.seek(0);
return filename;
} /**
* 获取上传文件的开始位置
* 开始位置会因为from 表单的参数不同而不同
* 如果from表单只上传文件是从第四行开始
* 本例from表单还有一个title的input , 所以从第八行开始。每多一个参数就加四行。
* @param randomFile
* @return 上传文件的开始位置
* @throws IOException
*/
private long getFileEnterPosition(RandomAccessFile randomFile)throws IOException{
long enterPosition = 0;
int forth = 1;
int n ;
while((n=randomFile.readByte())!=-1&&(forth<=8)){
if(n=='\n'){
enterPosition = randomFile.getFilePointer();
forth++;
}
}
return enterPosition;
} /**
* 获取上传文件的结束位置
* 结束位置会因为文件类型不同,而不同
* 压缩包是倒数第二行后
* @param randomFile
* @return 文件的结束位置
* @throws IOException
*/
private long getFileEndPosition(RandomAccessFile randomFile)throws IOException{
randomFile.seek(randomFile.length());
long endPosition = randomFile.getFilePointer();
int j = 1;
while((endPosition>=0)&&(j<=2)){
endPosition--;
randomFile.seek(endPosition);
if(randomFile.readByte()=='\n'){
j++;
}
}
return endPosition;
} /**
* 检查要保存文件的文件夹是否存在
*/
private void checkFold(){
File file = new File(this.fileFolder);
if (!file.exists()){
file.mkdirs();
}
} /**
* 将临时文件解析后存放到指定的文件存放目录
* @param randomFile
* @param forthEnterPosition
* @param filename
* @return fileSize
* @throws IOException
*/
private long saveFile(RandomAccessFile randomFile,String filename)throws IOException{
File saveFile = new File(this.fileFolder,filename);
RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile,"rw"); long forthEnterPosition = getFileEnterPosition(randomFile);
long endPosition = getFileEndPosition(randomFile);
//从上传文件数据的开始位置到结束位置,把数据写入到要保存的文件中
randomFile.seek(forthEnterPosition);
long startPoint = randomFile.getFilePointer();
while(startPoint<endPosition){
randomAccessFile.write(randomFile.readByte());
startPoint = randomFile.getFilePointer();
}
long fileSize = randomAccessFile.length();
randomAccessFile.close();
return fileSize;
}
}

接着是下载的Servlet代码

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class Download extends HttpServlet { private static final long serialVersionUID = 1L;
private static final String FILEDIR="files/_file";
private String fileFolder; //存文件的目录 public Download() {
super();
} public void destroy() {
super.destroy();
// Put your code here
} public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// request.setCharacterEncoding("UTF-8");
try{
String fileName = request.getParameter("name");
OutputStream outputStream = response.getOutputStream();
//输出文件用的字节数组,每次向输出流发送600个字节
byte b[] = new byte[600]; File fileload = new File(this.fileFolder,fileName); fileName=encodeFileName(request,fileName);
//客服端使用保存文件的对话框
response.setHeader("Content-disposition", "attachment;filename="+fileName);
//通知客户文件的长度
long fileLength = fileload.length();
String length = String.valueOf(fileLength);
response.setHeader("Content_length", length);
//读取文件,并发送给客服端下载
FileInputStream inputStream = new FileInputStream(fileload);
int n = 0;
while((n=inputStream.read(b))!=-1){
outputStream.write(b,0,n);
}
}catch(FileNotFoundException fnfe){
fnfe.printStackTrace();
try{
PrintWriter out = response.getWriter();
out.println("下载的文件不存在");
out.flush();
out.close();
}catch(IOException ie){
ie.printStackTrace();
}
}catch(IOException ie){
ie.printStackTrace();
try{
PrintWriter out = response.getWriter();
out.println("下载存在问题");
out.flush();
out.close();
}catch(IOException iex){
iex.printStackTrace();
}
}
} /**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
this.fileFolder = getServletContext().getRealPath("/")+"files/_file";
} private String encodeFileName(HttpServletRequest request,String fileName){
try{
//IE
if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") >0){
fileName=URLEncoder.encode(fileName,"UTF-8");
}else{
fileName = new String(fileName.getBytes("UTF-8"),"ISO8859-1");
}
}catch(Exception ex){
ex.printStackTrace();
}
return fileName;
} }
												

Servlet 实现文件的上传与下载的更多相关文章

  1. jsp+servlet实现文件的上传和下载

    实现文件的上传和下载首先需要理解几个知识,这样才可以很好的完成文件的上传和下载: (1):上传文件是上传到服务器上,而保存到数据库是文件名 (2):上传文件是以文件转换为二进制流的形式上传的 (3): ...

  2. Servlet之文件的上传与下载

    文件上传和文件下载是我们学JAVA Web时必不可少的模块.今天我们探讨下这个问题 文件上传: request.setCharacterEncoding("utf-8");//设置 ...

  3. 在SpringMVC框架下实现文件的 上传和 下载

    在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8" ...

  4. 初学Java Web(7)——文件的上传和下载

    文件上传 文件上传前的准备 在表单中必须有一个上传的控件 <input type="file" name="testImg"/> 因为 GET 方式 ...

  5. java web(四):request、response一些用法和文件的上传和下载

    上一篇讲了ServletContent.ServletCOnfig.HTTPSession.request.response几个对象的生命周期.作用范围和一些用法.今天通过一个小项目运用这些知识.简单 ...

  6. java实现文件的上传和下载

    1. servlet 如何实现文件的上传和下载? 1.1上传文件 参考自:http://blog.csdn.net/hzc543806053/article/details/7524491 通过前台选 ...

  7. Spring MVC 实现文件的上传和下载

    前些天一位江苏经贸的学弟跟我留言问了我这样一个问题:“用什么技术来实现一般网页上文件的上传和下载?是框架还是Java中的IO流”.我回复他说:“使用Spring MVC框架可以做到这一点,因为Spri ...

  8. 文件的上传和下载--SpringMVC

    文件的上传和下载是项目开发中最常用的功能,例如图片的上传和下载.邮件附件的上传和下载等. 接下来,将对Spring MVC环境中文件的上传和下载进行详细的讲解. 一.文件上传 多数文件上传都是通过表单 ...

  9. java 文件的上传和下载

    主要介绍使用 smartupload.jar 包中的方法对文件的上传和下载.上传时文件是存放在服务器中,我用的是tamcat. 首先建立一个servlet 类,对文件的操作 package com.d ...

随机推荐

  1. [转载]Android 知识图谱

    from: http://blog.csdn.net/xyz_lmn/article/details/41411355

  2. centos 安装 erlang

    1.首先下载erlang 安装源文件 可以在官网上下载 : http://www.erlang.org/   官网上提供多个版本:   2.下载完成后将R16B01 Source File对应的 ot ...

  3. [小知识点]IE6下不支持:hover的解决方法

    在网上百度到的解决办法,感觉不错,和大家分享一下. 在CSS样式里加一句代码"body{behavior:url("文件夹/csshover.htc");}"即 ...

  4. JS中window.document对象

    小知识点注:外面双引号,里面的双引号改为单引号:                  在div里面行高设置和整个外面高度一样,才能用竖直居中,居中是行居中                  文本框取出来 ...

  5. JavaScript基础知识----六道有趣的Js基础题以及解答

    题目: 1.找出数字数组中最大的元素(使用Math.max函数)2.转化一个数字数组为function数组(每个function都弹出相应的数字)3.给object数组进行排序(排序条件是每个元素对象 ...

  6. thinkphp小技巧

    if(IS_POST) _404("页面不存在",U("index"))               //如果不是POST提交,则跳转到index.debug模 ...

  7. ASP.NET JQuery 随笔-搜索框默认提示

    一.文本框中创建默认文本提示 通常用户在搜索内容时,在文本框输入内容前,文本框都会给出默认提示,提示用户输入正确的内容进行搜索. 当文本框获得焦点,如果文本框内容跟提示内容一样,提示内容会自然消失. ...

  8. SiteMesh

    1.导入对SiteMesh.jar的依赖 <dependency>      <groupId>org.sitemesh</groupId>      <ar ...

  9. 让我们共同构筑物联网起飞的平台:物联网操作系统Hello China寻求应用合作伙伴

    经过几天的努力,终于把Hello China V1.76版的内核移植到基于Cortex-M3内核的STM32 chipset上.因为还希望进一步写一个USART驱动程序,因此详细的移植文档,预计一周之 ...

  10. linux下的压缩解压命令 tar 的简单描述

    命令名称:tar 命令所在路径:/bin/tar 语法:tar选项·「-zcf」·「压缩后文件名」「目录」 -c 打包 -v 显示详细信息 -f 指定文件名 -z 打包同时压缩 tar命令解压缩语法: ...