Java文件上传下载

    

基于Java文件输入输出流的文件上传下载功能实现

   原理:    前端通过form表单的enctype属性,将数据传递方式修改为二进制”流“的形式,服务端(servlet)通过  getInputStream() 获取流信息, 运用java I/O 流的基础操作将流写入到一个服务端临时创建的文件temp中,然后再次利用文件基本操作,读取并截取临时文件内容,根据其中信息创建相应的文件,将读取出来的具体信息写入,下载时,根据提交的文件名称,找到服务器端相应的文件,然后根据输出流outStream输出到页面,同时将servlet的响应类型和响应头进行设置。

                                                                           

 

具体传输流程如下图:

 流信息的部分为:

具体代码如下:

前端代码:

 1 <html>
 2 <head>
 3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 4 <title>Insert title here</title>
 5 <script src="Js/jquery.js"></script>
 6 </head>
 7 <body>
 8   <form action="FileUpServlet" method="post" enctype="multipart/form-data">
 9    <table>
10     <tr>
11       <td>请选择上传文件:</td><td><input id="myfile" name="myfile" type="file" value="" /></td>
12       <td><input type="submit" value="上传"></td>
13     </tr>
14     <tr><td>${info}</td></tr>
15    </table> 
16   </form>
17         文件下载:<a href="FileLoadownServlet?filename=${filename}">${filename}</a>
18 </body>
19 </html>
View Code

 

上传servlet部分(核心)

  1 @WebServlet("/FileUpServlet")
  2 public class FileUpServlet extends HttpServlet {
  3     private static final long serialVersionUID = 1L;
  4        
  5     /**
  6      * @see HttpServlet#HttpServlet()
  7      */
  8     public FileUpServlet() {
  9         super();
 10         // TODO Auto-generated constructor stub
 11     }
 12 
 13     /**
 14      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 15      */
 16     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 17         // TODO Auto-generated method stub
 18         doPost(request, response);
 19     }
 20 
 21     /**
 22      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 23      */
 24     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 25         // TODO Auto-generated method stub
 26         request.setCharacterEncoding("utf-8");
 27         InputStream filesource = request.getInputStream();//request获取流信息
 28         String tempname = "D:/temp";//tempfile代表临时存放文件
 29         File tempfile = new File(tempname);//创建临时文件
 30         
 31         FileOutputStream outputStream = new FileOutputStream(tempfile);//输出流对象,指定输出指tempfile目录下
 32         byte b[] = new byte[1024];
 33         int n;
 34         while((n = filesource.read(b))!= -1)//从输出流中每次读取1024字节,直至读完
 35         {
 36             outputStream.write(b,0,n);
 37         }
 38         outputStream.close();
 39         filesource.close();//关闭输入输出流
 40         
 41         
 42         /*以下为具体的文件操作,主要为解析临时产生的 temp文件 ,知识多为java输入输出流的内容!*/
 43         
 44 
 45         RandomAccessFile randomfile = new RandomAccessFile(tempfile, "r");//随机流,指定要读临时文件,只读
 46         randomfile.readLine();//读取第一行,无效数据,不需要
 47

              String strs = randomfile.readLine();//读取第二行

               byte t[] = strs.getBytes("iso-8859-1");
               String str = new String(t,"utf-8");//读取乱码问题,根据不同的机器编码决定所填信息


48 int beginIndex = str.lastIndexOf("=")+2;//指定所需数据的开始位置 49 int endIndex = str.lastIndexOf("\"");//指定所需数据截至位置 50 String filename = str.substring(beginIndex,endIndex);//截取文件名 51 52 //重新定位文件指针,获取文件内容 53 randomfile.seek(0);//文件指针从头开始 54 long startext = 0; 55 int i = 1; 56 //文件内容开始位置 57 while((n=randomfile.readByte()) != -1&&i <= 4) 58 { 59 if(n=='\n') 60 { 61 startext = randomfile.getFilePointer(); 62 i++; 63 } 64 } 65 startext = randomfile.getFilePointer() - 1; 66 //获取文件内容 结束位置 67 randomfile.seek(randomfile.length()); 68 long endtext = randomfile.getFilePointer(); 69 int j = 1; 70 while(endtext >= 0 && j <= 2) 71 { 72 endtext--; 73 randomfile.seek(endtext); 74 if(randomfile.readByte()=='\n') 75 { 76 j++; 77 } 78 } 79 endtext = endtext-1; 80 81 //将临时文件保存至指定目录中 82 String realpath = getServletContext().getRealPath("/")+"images";//设置文件保存目录 83 System.out.println(realpath); 84 File fileupload = new File(realpath); 85 if(!fileupload.exists()) 86 { 87 fileupload.mkdir();//目录不存在则创建 88 } 89 File savefile = new File(realpath,filename); 90 RandomAccessFile randomAccessFile = new RandomAccessFile(savefile, "rw"); 91 randomfile.seek(startext); 92 while(startext<endtext){ 93 randomAccessFile.write(randomfile.readByte());//文件写入 94 startext = randomfile.getFilePointer(); 95 } 96 //关闭各种输入输出流 97 randomAccessFile.close(); 98 randomfile.close(); 99 tempfile.delete();//删除临时文件 100 101 102 SimpleDateFormat timed = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 103 Date nowdate = new Date(); 104 String time = timed.format(nowdate.getTime()); 105 request.setAttribute("info", time+" "+filename+"上传成功!"); 106 request.setAttribute("filename", filename); 107 request.getRequestDispatcher("/fildeOp.jsp").forward(request, response); 108 } 109 110 }

 注意:使用随机流RondomAccesFile流的readLine()方法在读取含有非ASCLL字符的文件时(如含有汉字)会出现乱码问题,具体对应以上代码截取文件名代码内容,

 解决方法具体为将readline读取来的信息转至byte格式,然后对其进行编码修改,再次转为String

 

1)读取

 

String strs = in.readLine();

 

(2)用 iso-8859-1 重新编码

 

byte b[] = strs.getBytes("iso-8859-1");

 

(3)使用当前机器的默认编码将字节数组转化为字符串

 

String content = new String(b);

 

如果当前机器默认编码是GB2312,那么,上面等价于:

 

String content = new String(b,"GB2312");

 

(有的是utf-8)

 

下载部分

 1 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2         // TODO Auto-generated method stub
 3         String filename = request.getParameter("filename");
 4         String path = getServletContext().getRealPath("/")+"images/";
 5         File file = new File(path+filename);//找到文件
 6         if(file.exists())
 7         {
 8             response.setContentType("application/x-msdownload"); //设置响应类型,此处为下载类型
 9             response.setHeader("Content-Disposition", "attachment;filename=\""+filename+"\"");//以附件的形式打开
10             InputStream inputStream = new FileInputStream(file);
11             ServletOutputStream outputStream = response.getOutputStream();
12             byte b[] = new byte[1024];
13             int n;
14             while((n = inputStream.read(b)) != -1)
15             {
16                 outputStream.write(b,0,n);
17             }
18             outputStream.close();
19             inputStream.close();            
20           }else{
21             request.setAttribute("result", "文件不存在!下载失败!");
22             request.getRequestDispatcher("/fildeOp.jsp").forward(request, response);
23         }
24     }

 补充!!!!:  此种方法的基本原理并非真正意义上的传输本地的文件,而是伪造一个假象,即服务端通过上传流数据,服务端接收 一堆流数据,存放至临时文件中,然后以文件IO操作读取解析临时文件,获取其中的文件名,以此在服务端相应目录下创建新文件,File xxx = new File(),然后继续读取临时文件,将其中内容存至服务端新文件中,在服务端制作一个一摸一样的文件来完成文件上传这个操作。  

 基于SmartUpload组件的文件上传下载

文件上传源码:

 

 1 @WebServlet("/SmartUploadServlet")
 2 public class SmartUploadServlet extends HttpServlet {
 3 
 4     public void doGet(HttpServletRequest req, HttpServletResponse resp)
 5             throws ServletException, IOException {
 6         doPost(req,resp);
 7     }
 8 
 9     public void doPost(HttpServletRequest req, HttpServletResponse resp)
10             throws ServletException, IOException {
11         //设置上传文件保存路径
12         String filePath = getServletContext().getRealPath("/") + "images";
13         File file = new File(filePath);
14         if(!file.exists()){
15             file.mkdir();
16         }
17         
18         SmartUpload su = new SmartUpload();
19         //初始化对象
20         su.initialize(getServletConfig(), req, resp);
21         //设置上传文件大小
22         su.setMaxFileSize(1024*1024*10);
23         //设置所有文件的大小
24         su.setTotalMaxFileSize(1024*1024*100);
25         //设置允许上传文件类型
26         su.setAllowedFilesList("txt,jpg,gif");
27         String result = "上传成功!";
28         //设置禁止上传的文件类型
29         try {
30             su.setDeniedFilesList("rar,jsp,js");
31             //上传文件
32             su.upload();
33             
34             int count = su.save(filePath);
35             System.out.println("上传成功" +  count + "个文件!");
36         } catch (Exception e) {
37             result = "上传失败!";
38             e.printStackTrace();
39         }
40 
41         req.setAttribute("result", result);
42         req.getRequestDispatcher("formFile.html").forward(req, resp);
43     }
44 
45 }

 

文件下载源码:

 1 @WebServlet("/SmartDownloadServlet")
 2 public class SmartDownloadServlet extends HttpServlet {
 3 
 4     public void doGet(HttpServletRequest request, HttpServletResponse response)
 5             throws ServletException, IOException {
 6         doPost(request,response);
 7     }
 8 
 9     public void doPost(HttpServletRequest request, HttpServletResponse response)
10             throws ServletException, IOException {
11 
12         String filename = request.getParameter("filename");
13         
14         SmartUpload su = new SmartUpload();
15         su.initialize(getServletConfig(), request, response);
16         su.setContentDisposition(null);
17         try {
18             su.downloadFile("/images/"+ filename);
19         } catch (SmartUploadException e) {
20             e.printStackTrace();
21         }
22     }
23 
24 }

 

转载于:https://www.cnblogs.com/TheGCC/p/8951774.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值