一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - java文件上傳技術深入剖析

java文件上傳技術深入剖析

2020-06-22 11:44xanlv JAVA教程

這篇文章主要為大家詳細介紹了java文件上傳技術深入剖析,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了java文件上傳技術,供大家參考,具體內容如下

java文件上傳技術深入剖析

表單:
客戶端發送HTTP必須使用multipart/form-data數據類型,表示復合數據類型。即:
在表單中使用html標簽。

需要的包:
        Commons-fileupload.jar,核心上傳文件工具都在這個包中。
        commons-io.jar – 上傳文件所需要的包

上傳文件類詳解:
DiskFileItemFactory-創建監時文件目錄,指是緩存區大小
ServletFileUpload用于解析HttpServletRequest。返回一組文件對象。
FileItem – 表示用戶上傳的每一個文件對像。

 

?
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
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
 
  <title>文件上傳演示</title>
 </head>
 
 <body>
  <font color="red" size="6">過渡板--了解底層</font>
  <!-- multipart/form-data:多部分(不但有文件,也有部分) -->
  <form action="<%=request.getContextPath()%>/upload0" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="file"/>
    <input type="submit" value="上傳"/>
    <!-- 上傳的文件名不能為中文,否則獲取的文件名是亂碼,不過下面的例子可以解決這個問題 -->
  </form>
  <br/>
 
 
  <font color="red" size="6">使用apache文件上傳工具實現文件上傳</font>
  <!-- application/x-www-form-urlencoded -->
  <form action="<%=request.getContextPath()%>/upload" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="file"/>
    <input type="submit" value="上傳"/> 
  </form>
 
 
  <font color="red" size="6">使用apache文件上傳工具實現文件上傳2(解決文件名亂碼)</font>
  <p>
  POST1(普通表單):enctype=application/x-www-form-urlencoded(默認值)
  </p>
  <p>
  POST2(上傳文件表單):enctype=multipart/form-data:多部分(不但有文件,也有部分)
  </p>
  <form action="<%=request.getContextPath()%>/upload2" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="file"/><!-- POST2(上傳文件表單) --><br/>
    文件說明:<input type="text" name="desc"/><!-- POST1(普通表單) --><br/><br/>
    文件2:<input type="file" name="file"/><br/>
    文件說明2:<input type="text" name="desc"/>
    <input type="submit" value="上傳"/> 
  </form>
  <font color="red" size="6">使用apache文件上傳工具實現文件上傳3(文件打散)</font>
  <!-- POST1(普通表單):enctype=application/x-www-form-urlencoded(默認值) -->
  <!-- POST2(上傳文件表單):enctype=multipart/form-data:多部分(不但有文件,也有部分) -->
  <form action="<%=request.getContextPath()%>/upload3" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="file"/><!-- POST2(上傳文件表單) --><br/>
    文件說明:<input type="text" name="desc"/><!-- POST1(普通表單) --><br/><br/>
    文件2:<input type="file" name="file"/><br/>
    文件說明2:<input type="text" name="desc"/>
    <input type="submit" value="上傳"/> 
  </form>
 </body>
</html>

java文件上傳技術深入剖析

過渡板–了解底層

 

?
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
package cn.hncu.servlet;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class Upload0Servlet extends HttpServlet {
 
 
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
 
    InputStream in=request.getInputStream();
    BufferedReader br=new BufferedReader(new InputStreamReader(in));
    String line;
    while((line=br.readLine())!=null){
      System.out.println(line);
    }
  }
 
}

java文件上傳技術深入剖析

java文件上傳技術深入剖析

使用apache文件上傳工具實現文件上傳

 

?
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
package cn.hncu.servlet;
 
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
 
public class UploadServlet extends HttpServlet {
 
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
 
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
    out.println("<HTML>");
    out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
    out.println(" <BODY>");
    out.print("不支持Get方式上傳。。。。。。");
    out.println(" </BODY>");
    out.println("</HTML>");
    out.flush();
    out.close();
  }
 
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
 
        //在服務器上,為所有上傳文件指定一個存放目錄
    String path=getServletContext().getRealPath("/upload");
    System.out.println("path:"+path);
    File dir=new File(path);
    if(!dir.exists()){
      dir.mkdirs();
    }
 
    //創建一個基于硬盤的工廠
    //DiskFileItemFactory disk = new DiskFileItemFactory();
    //設置臨時目錄(建議設計臨時目錄,否則會使用系統臨時目錄。)
    //disk.setRepository(new File(“d:/a”));
    //3、 設置向硬盤寫數據的緩沖區大小
disk.setSizeThreshold(1024*4);//當文件大于此設置時,將會在臨時目錄下形成臨時文件
 
 
    //設置臨時文件緩沖區大小--8K緩沖,臨時文件地址
    DiskFileItemFactory f=new DiskFileItemFactory(1024*8, new File("d:/a"));
    //上傳工具--創建用于解析的對像
    ServletFileUpload upload=new ServletFileUpload(f);
    upload.setFileSizeMax(1024*1024*5);//設置上傳的單個文件最大為5M
    //設置上傳文件的最大大小,如果是多個文件,則為多個文件的和最大8M
    upload.setSizeMax(1024*1024*8);//設置所有上傳的文件大小之和最大為8M
    //使用解析工具解析
    try {
      List<FileItem> list=upload.parseRequest(request);
      for(FileItem fI:list){
        System.out.println("文件內容類型:"+fI.getContentType());//文件內容類型:text/plain
        System.out.println("文件名:"+fI.getName());//文件名:C:\Users\adl1\Desktop\a.txt
        String ext=fI.getName().substring(fI.getName().lastIndexOf("."));//.txt
        String uuid=UUID.randomUUID().toString().replace("-", "");
        String fileName=uuid+ext;
//       FileUtils.copyInputStreamToFile(fI.getInputStream(), new File("d:/a/d/a.txt"));//寫死了
        //fI.getInputStream()是真正文件信息
        FileUtils.copyInputStreamToFile(fI.getInputStream(), new File(path+"/"+fileName));//寫活了
      }
    } catch (FileUploadException e) {
      e.printStackTrace();
    }
 
 
  }
 
}

在這個地方存儲上傳的文件

java文件上傳技術深入剖析

上傳信息:

java文件上傳技術深入剖析

上傳結果:

java文件上傳技術深入剖析

使用apache文件上傳工具實現文件上傳2(解決文件名亂碼)

 

?
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
package cn.hncu.servlet;
 
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
 
public class Upload2Servlet extends HttpServlet {
 
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
 
 
    response.setContentType("text/html");
    //如果是含上傳文件的表單(POST2),該劇只能設置所上傳文件的文件名中的編碼(解決他的中文亂碼)
    //但不能解決在POST2方式下的普通表單組件的中文亂碼
    PrintWriter out = response.getWriter();
    out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
    out.println("<HTML>");
    out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
    out.println(" <BODY>");
    out.print("不支持Get方式上傳。。。。。。");
    out.println(" </BODY>");
    out.println("</HTML>");
    out.flush();
    out.close();
  }
 
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
 
    //第一步
    //普通的form表單(POST1),下面這句可以設置普通表單組件內容的編碼(能夠解決它們的中文亂碼問題)
    request.setCharacterEncoding("utf-8");
    //如果是含上傳文件的表單(POST2),該句只能設置所上傳文件的文件名中的編碼(解決它的中文亂碼)。但不能解決普通表單組件的亂碼(不能設它編碼)
 
 
    //在服務器上,為所有上傳文件指定一個存放目錄
    String path=getServletContext().getRealPath("/upload");
    System.out.println("path:"+path);
    File dir=new File(path);
    if(!dir.exists()){
      dir.mkdirs();
    }
 
 
    //設置臨時文件緩沖區大小--8K緩沖,臨時文件地址
    DiskFileItemFactory f=new DiskFileItemFactory(1024*8, new File("d:/a"));
    //上傳工具
    ServletFileUpload upload=new ServletFileUpload(f);
    upload.setFileSizeMax(1024*1024*5);//設置上傳的單個文件最大為5M
    upload.setSizeMax(1024*1024*8);//設置所有上傳的文件大小之和最大為8M
    //使用解析工具解析
    try {
      List<FileItem> list=upload.parseRequest(request);
      for(FileItem fI:list){
        if((fI.isFormField())){//如果是普通表單組件:checkbox,radio,password...
//         String desc=fI.getString();
          System.out.println("fI.getString():"+fI.getString());
          //第二步
          String desc=fI.getString("utf-8");
          //該句設置普通表單組件內容編碼
          System.out.println("編碼后:"+desc);
        }else{
          String ext=fI.getName().substring(fI.getName().lastIndexOf("."));//.txt
          String uuid=UUID.randomUUID().toString().replace("-", "");
          String fileName=uuid+ext;
          //fI.getInputStream()是真正文件信息
          FileUtils.copyInputStreamToFile(fI.getInputStream(), new File(path+"/"+fileName));//寫活了
        }
      }
    } catch (FileUploadException e) {
      e.printStackTrace();
    }
  }
}

上傳信息:

java文件上傳技術深入剖析

上傳結果:


java文件上傳技術深入剖析

使用apache文件上傳工具實現文件上傳3(文件打散)

用Hash目錄優化文件存儲:
Hash目錄是一種優化文件存儲性能的方法。無論是Windows還是Linux,無論是NTFS還是ext3,每個目錄下所能容納的項目數是有限的。
并不是不能保存,而是當項目數量過大的時候,會降低文件索引速度,
所以權衡一個目錄下應該保存多少文件是很必要的。保存得多了會影響性能,保存得少了會造成目錄太多和空間浪費。所以當保存大批文件的時候,
需要有一種算法能將文件比較均勻地“打散”在不同的子目錄下以提高每一級的索引速度,這種算法就是 Hash。通常用的MD5、sha1等都可以用來做Hash目錄,我的Session里也同樣使用了MD5,取得sessionID的第一位和第九位,這就構成了兩級Hash路徑,也就是說,系統把所有的Session文件分散到了16×16=256個子目錄下。假設Linux每個目錄下保存1000個文件可以獲得最好的空間性能比,那么系統在理想情況下可以同時有256000個session文件在被使用。

 

?
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package cn.hncu.servlet;
 
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
 
public class Upload3Servlet extends HttpServlet {
 
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
 
 
    response.setContentType("text/html");
    //如果是含上傳文件的表單(POST2),該劇只能設置所上傳文件的文件名中的編碼(解決他的中文亂碼)
    //但不能解決在POST2方式下的普通表單組件的中文亂碼
    PrintWriter out = response.getWriter();
    out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
    out.println("<HTML>");
    out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
    out.println(" <BODY>");
    //獲取GET方式的url中“?”號后面的部分
    //http://localhost:8080/servletDemo3/upload?name=Jack&sex=male
    String qStr = request.getQueryString();
    System.out.println("qStr: "+qStr);//qStr: name=Jack&sex=male
    out.print("不支持Get方式上傳。。。。。。");
    out.println(" </BODY>");
    out.println("</HTML>");
    out.flush();
    out.close();
  }
 
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
 
    response.setContentType("text/html;charset=utf-8");
    PrintWriter out = response.getWriter();
    //1防黑: 防護前端采用POST1方式提交
    //法1
    /*
    String type=request.getContentType();
    if(!type.contains("multipart/form-data")){
      out.println("不支持普通表單提交");
      return;
    }*/
    //法2
    boolean boo = ServletFileUpload.isMultipartContent(request);
    if(!boo){
      out.println("不支持普通表單提交");
      return;
    }
 
    //第一步
    //普通的form表單(POST1),下面這句可以設置普通表單組件內容的編碼(能夠解決它們的中文亂碼問題)
    request.setCharacterEncoding("utf-8");
    //如果是含上傳文件的表單(POST2),該句只能設置所上傳文件的文件名中的編碼(解決它的中文亂碼)。但不能解決普通表單組件的亂碼(不能設它編碼)
 
 
    //在服務器上,為所有上傳文件指定一個存放目錄
    String path=getServletContext().getRealPath("/upload");
    System.out.println("path:"+path);
    File dir=new File(path);
    if(!dir.exists()){
      dir.mkdirs();
    }
 
 
    //設置臨時文件緩沖區大小--8K緩沖,臨時文件地址
    DiskFileItemFactory f=new DiskFileItemFactory(1024*8, new File("d:/a"));
    //上傳工具
    ServletFileUpload upload=new ServletFileUpload(f);
    upload.setFileSizeMax(1024*1024*5);//設置上傳的單個文件最大為5M
    upload.setSizeMax(1024*1024*8);//設置所有上傳的文件大小之和最大為8M
 
    //▲4上傳進度監聽
    upload.setProgressListener(new ProgressListener(){
      private double pre=0D;
      @Override//參數1:已上傳多少字節 參數2:一共多少字節  參數3:第幾個文件(序號從1開始)
      public void update(long pByteRead, long pContentLength, int pItems) {
        double d = 1.0*pByteRead/pContentLength*100;
        System.out.println(d+"%");
            if(pre!=d){
              System.out.println(d+"%");
              pre=d;
            }
      }
    });
 
 
    //使用解析工具解析
    try {
      List<FileItem> list=upload.parseRequest(request);
      for(FileItem fI:list){
        if((fI.isFormField())){//如果是普通表單組件:checkbox,radio,password...
//         String desc=fI.getString();
          System.out.println("fI.getString():"+fI.getString());
          //第二步
          String desc=fI.getString("utf-8");
          //該句設置普通表單組件內容編碼
          System.out.println("編碼后:"+desc);
        }else{
          //防護:過濾掉沒選擇文件的空文件組件
          if(fI.getSize()<=0){
            continue;//讀下一個文件
          }
 
          System.out.println("文件內容類型:"+fI.getContentType());//文件內容類型:text/plain
          System.out.println("文件名:"+fI.getName());//文件名:C:\Users\adl1\Desktop\a.txt
 
          String ext=fI.getName().substring(fI.getName().lastIndexOf("."));//.txt
          String uuid=UUID.randomUUID().toString().replace("-", "");
          String fileName=uuid+ext;
 
          //文件目錄打散技術
          String dir1=Integer.toHexString(uuid.hashCode()&0x0f);
          String dir2=Integer.toHexString((uuid.hashCode()&0xf0)>>4);
 
 
          //fI.getInputStream()是真正文件信息
          FileUtils.copyInputStreamToFile(fI.getInputStream(), new File(path+"/"+dir1+"/"+dir2+"/"+fileName));//寫活了
        }
      }
    } catch (FileUploadException e) {
      e.printStackTrace();
    }
  }
}

打散信息:

java文件上傳技術深入剖析

打散結果:

文件1:

java文件上傳技術深入剖析

文件2:

java文件上傳技術深入剖析

演示上傳進度原理

java文件上傳技術深入剖析

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩v| 日本大片免a费观看在线 | 欧美黑人换爱交换乱理伦片 | 九九久久国产精品免费热6 九九精品视频一区二区三区 | 久久99精品涩AV毛片观看 | 性插图动态图无遮挡 | 天天爽天天 | 成人免费在线视频观看 | 国产在线91 | 午夜在线观看视频 | 青柠在线完整高清观看免费 | 欧美午夜寂寞影院安卓列表 | 亚洲第一区欧美日韩精品 | 午夜在线播放免费人成无 | 欧美一卡二卡科技有限公司 | 97香蕉超级碰碰碰久久兔费 | 男人机机桶女人 | oneday日本在线观看完整版 | 四虎黄色网址 | 视频在线观看大片 | 手机看片黄色 | www.国产一区二区三区 | 精品国产免费一区二区三区 | 成人免费毛片一区二区三区 | 极致堕落(高h) | 波多野结衣女教师在线观看 | 日产乱码卡一卡2卡三卡四福利 | 精品国产免费第一区二区三区日韩 | 99精品久久精品一区二区小说 | 国产小视频在线免费 | 欧美日韩精品一区二区三区高清视频 | a在线观看欧美在线观看 | 教师系列 大桥未久在线 | 青青草视频国产 | 日本在线观看www免费 | 5151hh四虎国产精品 | 精品一区在线 | 国产a一级毛片爽爽影院 | 欧美日韩一区二区三区在线视频 | 美女黄金大片视频免费看 | 国产66|