文件上传与下载

文件上传

文件上传的几个步骤:

1   获得上传路径   如果上传的文件需要安全的存放 则应该放在WEB-INF  下面

  String  savePath=request.getServletContext().getRealPath("/WEB-INF/upload1");

 

2    创建解析工厂

  DiskFileItemFactory diskFileItemFactory=new DiskFileItemFactory();

3   创建解析器

  ServletFileUpload  servletFileUpload=new ServletFileUpload(diskFileItemFactory);

 

4   判断是不是表单数据(如果是表单数据 继续进行后面操作)

  ServletFileUpload.isMultipartContent(request)

5   使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项

  List<FileItem>  list=servletFileUpload.parseRequest(request);

6   遍历每一个FileItem

7   如果FileItem是普通表单项,则按普通表单项处理方式处理(取值),如果是文件则进行后面操作

  fileItem.isFormField()

8   获取上传文件的名字(通过截取字段获得真实名字)

 (1) String fileName=fileItem.getName();

  此名字字符串包含包含一些系统路径,如下面这个字符串所示。

  C:\Windows\Installer\{90140000-0011-0000-0000-0000000FF1CE}\graph.ico

    (2)  截取字符串  获得真实名字

  fileName=fileName.substring(fileName.lastIndexOf("\\")+1);

9  将fileItem写入流中(方便后面写到磁盘中)

  InputStream in=fileItem.getInputStream();

10    创建输出流  并将输入流中的数据写入输出流中,并删除临时文件

    FileOutputStream out = new FileOutputStream(sqlPath);

  

1
2
3
4
5
6
7
8
9
byte[] bytes=new byte[1024];
int l=0;
    while((l=in.read(bytes))!=-1){
        out.write(bytes, 0, l);
    }
                             
    //删除处理文件上传时生成的临时文件
     fileItem.delete();
    msg = "文件上传成功!";

  

文件下载的步骤:

1   获取传递过来的要下载的文件的路径和姓名参数

  String filename=req.getParameter("filename");
  String filepath=req.getParameter("filepath");

2    将要下载的文件放进输入流中

   InputStream in = new FileInputStream(filepath);

3   设置响应头,对文件进行url编码

  

1
2
filename = URLEncoder.encode(filename, "UTF-8");
resp.setHeader("Content-Disposition", "attachment;filename="+filename);

  

4  创建输出流  对文件进行copy

  

1
2
3
4
5
6
7
8
9
10
拷贝
      OutputStream out = resp.getOutputStream();
      byte[] b = new byte[1024];
      int len = 0;
      while((len = in.read(b))!=-1){
        out.write(b, 0, len);
      }
      out.flush();
      out.close();
      in.close()

 在本实例中   我设计了一个简单数据库file  (filename  文件名,filepath 文件路径),  采用dao模式   将上传的文件的路径和文件名保存在数据库中 ,在再前台页面中奖所有的已上传的文件读取出来显示在页面上 ,在使用文件下载的方式将其下载。

具体代码如下:

《一》 文件上传

  (1)前台页面

<form method="post" action="${pageContext.request.contextPath }/fileUpload1" enctype="multipart/form-data">
        上传者:<input type="text" name="username"></br>
        <input type="file" name="file"><br>
        <input type="file" name="file1"><br>
        <input type="submit" value="submit">
    </form>

  (2) web层   (上传成功后  跳转到file_uplodad/g.jsp  这个页面      注意要让文件全部操作完后再跳转,如果上传的时候有个以上文件,你在上传一个就跳转页面会程序报错)

  

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         
        FileUploadServices fileUploadServices=new FileUploadServices();
         
        /*获得上传路径*/
        String  savePath=request.getServletContext().getRealPath("/WEB-INF/upload1");
        File file=new File(savePath);
        if(!file.exists()){
            System.out.println(savePath+"不存在,请创建");
            file.mkdir();
        }
        String msg="";
        //1创建解析工厂
        DiskFileItemFactory diskFileItemFactory=new DiskFileItemFactory();
        //2创建解析器
        ServletFileUpload  servletFileUpload=new ServletFileUpload(diskFileItemFactory);
            //中文乱码问题
        servletFileUpload.setHeaderEncoding("utf-8");
        //3判断是不是表单数据
        if(!ServletFileUpload.isMultipartContent(request)){
            System.out.println("上传的不是表单数据");
        }
        //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
        try {
            List<FileItem>  list=servletFileUpload.parseRequest(request);
            for(FileItem fileItem:list){
                if(fileItem.isFormField()){
                    String name=fileItem.getName();
                    String value=fileItem.getString("utf-8");//解决乱码问题
                    System.out.println(name+"="+value);
                }
                else{
                    String fileName=fileItem.getName();//注意是getName  而不是getFileName()---file  表单中的
                if(fileName!=""){
                    System.out.println(fileName+"      fileName");
                     
                     
                     
                    //C:\Windows\Installer\{90140000-0011-0000-0000-0000000FF1CE}\graph.ico
                    //截取后面部分得到真实名字   \graph.ico
                    fileName=fileName.substring(fileName.lastIndexOf("\\")+1);
                    System.out.println(fileName+"截取后面部分得到真实名字");
                    //获取fileItem的输入流
                    InputStream in=fileItem.getInputStream();
                 
                    //创建一个文件输出流
                    Date date=new Date();
                     
                    SimpleDateFormat SimpleDateFormat=new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
                    String da=SimpleDateFormat.format(date);
                    String sqlPath=savePath + "\\" +da+"_"+ fileName;
                    System.out.println(sqlPath+"  sqlPath");
                    //sqlPath=sqlPath.replaceAll("\\", "/");
                    //判断是否上传了文件
                    System.out.println(sqlPath.substring(sqlPath.lastIndexOf("_")+1)+"dd");
                    if(sqlPath.substring(sqlPath.lastIndexOf("_")+1)!=" "){
                         FileOutputStream out = new FileOutputStream(sqlPath);
                            byte[] bytes=new byte[1024];
                            int l=0;
                            while((l=in.read(bytes))!=-1){
                                out.write(bytes, 0, l);
                            }
                             
                            //删除处理文件上传时生成的临时文件
                            fileItem.delete();
                            msg = "文件上传成功!";
                             
                            String sql="insert into file (filepath,filename) values(?,?)";
                            try {
                                if(sqlPath.substring(sqlPath.lastIndexOf("_")+1).length()>1){
                                    sqlPath=sqlPath.replace("\\", "/");
                                    /*pst=(PreparedStatement) conn.prepareStatement(sql);
                                     pst.setString(1,sqlPath );
                                     pst.setString(2,fileName );
                                     pst.execute();*/
                                    fileUploadServices.insert(sql,new Object[]{sqlPath,fileName});
                                }
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                    }
                     
                     
                }
            }
            }
        } catch (FileUploadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         
        response.sendRedirect("/file_uplodad/g.jsp");  
    }

  

  (3) services层

1
2
3
4
5
6
FileUploadDao fileUploadDao =new FileUploadDao();
    public void insert(String sql,Object ...obj) {
        // TODO Auto-generated method stub
        fileUploadDao.insert(sql,obj);
         
    }

  

  (4)dao层     

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  Connection conn=null;
ResultSet rs=null;
PreparedStatement stmt=null;
 
try {
    MyPool myPool=new MyPool(10);  ///自己写的简单连接池 
    conn=myPool.getConnection();
      // 设置参数
    stmt=(PreparedStatement) conn.prepareStatement(sql);
    ParameterMetaData parameterMetaData;
    parameterMetaData = stmt.getParameterMetaData();
      int count =parameterMetaData.getParameterCount();
      for (int i = 1; i <= count; i++) {
            stmt.setObject(i, obj[i - 1]);
        }
      stmt.executeUpdate();
      conn.close();

  

 

 

《二》 文件下载

  文件下载dao模式和上传的差不多 ,只是从数据库中将文件名和文件路径显示出来,并作为下载时的传递参数给文件下载的servlet  这里 我就只展示文件下载的servlet 

  

下载传递的参数:

<a href="${pageContext.request.contextPath }/download?filepath=<%=list.get(i).getFilepath()%>&filename=<%=list.get(i).getFilename() %>">下载</a>

 

 

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
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //第一步:设置响应类型
        resp.setContentType("application/force-download");//应用程序强制下载
        //第二读取文件
      //  String path = getServletContext().getRealPath("/up/"+name);
        String filename=req.getParameter("filename");
        String filepath=req.getParameter("filepath");
        System.out.println(filename+"   filename");
        System.out.println(filepath+ "      filepath");
        InputStream in = new FileInputStream(filepath);
        //设置响应头,对文件进行url编码
        filename = URLEncoder.encode(filename, "UTF-8");
        resp.setHeader("Content-Disposition", "attachment;filename="+filename);  
        //resp.setContentLength(in.available());
         
        //第三步:拷贝
        OutputStream out = resp.getOutputStream();
        byte[] b = new byte[1024];
        int len = 0;
        while((len = in.read(b))!=-1){
          out.write(b, 0, len);
        }
        out.flush();
        out.close();
        in.close();
        

  

在将上传的文件路径存入数据库之前 课改替换掉路径中的"\",故用到两个方法replace(),replaceAll(),

replace和replaceAll是JAVA中常用的替换字符的方法,它们的区别是:

1)replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence即字符串序列的意思,说白了也就是字符串);

2)replaceAll的参数是regex,即基于规则表达式的替换,比如,可以通过replaceAll("\\d", "*")把一个字符串所有的数字字符都换成星号;

相同点:都是全部替换,即把源字符串中的某一字符或字符串全部换成指定的字符或字符串,如果只想替换第一次出现的,可以使用replaceFirst(),这个方法也是基于规则表达式的替换,但与replaceAll()不同的是,只替换第一次出现的字符串;

另外,如果replaceAll()和replaceFirst()所用的参数据不是基于规则表达式的,则与replace()替换字符串的效果是一样的,即这两者也支持字符串的操作;

还有一点注意::执行了替换操作后,源字符串的内容是没有发生改变的。

  举例如下:  

1
2
3
4
5
6
7
8
9
10
11
12
13
String src = new String("ab43a2c43d");
  
System.out.println(src.replace("3","f"));=>ab4f2c4fd.
  
System.out.println(src.replace('3','f'));=>ab4f2c4fd.
  
System.out.println(src.replaceAll("\\d","f"));=>abffafcffd.
  
System.out.println(src.replaceAll("a","f"));=>fb43fc23d.
  
System.out.println(src.replaceFirst("\\d,"f"));=>abf32c43d
  
System.out.println(src.replaceFirst("4","h"));=>abh32c43d.

  

如何将字符串中的"\"替换成"\\": 

1
2
3
4
5
String msgIn;
  
String msgOut;
  
msgOut=msgIn.replaceAll("\\\\","\\\\\\\\");<br><br>

 

原因:

  '\'在java中是一个转义字符,所以需要用两个代表一个。例如System.out.println( "\\" ) ;只打印出一个"\"。但是'\'也是正则表达式中的转义字符(replaceAll 的参数就是正则表达式),需要用两个代表一个。所以:\\\\被java转换成\\,\\又被正则表达式转换成\。

 

将"\"替换成"/"

 String sqlPath="C:\Windows.old\Users";

1
sqlPath=sqlPath.replace("\\", "/");

 

posted @ 2018-06-23 13:31  温一壶月光当茶饮  阅读(273)  评论(0)    收藏  举报
点击右上角即可分享
微信分享提示