java文件上传下载

Posted 王超元

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java文件上传下载相关的知识,希望对你有一定的参考价值。

文件上传首先要引入两个核心包

commons-fileupload-1.2.1.jar

commons-io-1.4.jar

 

下面是对文件上传和下载的一些代码做的一个简单封装,可以方便以后直接使用【使用时将封装好的jar包直接导入工程中即可使用】

 

上传文件核心代码

复制代码
  1 package com.lizhou.fileload;
  2 
  3 import java.io.File;
  4 import java.io.FileOutputStream;
  5 import java.io.IOException;
  6 import java.io.InputStream;
  7 import java.io.OutputStream;
  8 import java.util.ArrayList;
  9 import java.util.List;
 10 import java.util.UUID;
 11 
 12 import javax.servlet.http.HttpServletRequest;
 13 
 14 import org.apache.commons.fileupload.FileItem;
 15 import org.apache.commons.fileupload.FileUploadException;
 16 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 17 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 18 
 19 import com.lizhou.exception.FileFormatException;
 20 import com.lizhou.exception.NullFileException;
 21 import com.lizhou.exception.ProtocolException;
 22 import com.lizhou.exception.SizeException;
 23 
 24 /**
 25  * 上传文件
 26  * @author bojiangzhou
 27  *
 28  */
 29 public class FileUpload {
 30     /**
 31      * 上传文件用的临时目录
 32      */
 33     private String tempPath = null;
 34     /**
 35      * 上传文件用的文件目录
 36      */
 37     private String filePath = null;
 38     /**
 39      * 内存中缓存区的大小,默认100k
 40      */
 41     private int bufferSize = 100;
 42     /**
 43      * 上传文件的最大大小,默认1M
 44      */
 45     private int fileSize = 1000;
 46     /**
 47      * 上传文件使用的编码方式,默认UTF-8
 48      */
 49     private String encoding = "UTF-8";
 50     /**
 51      * 上传文件的格式,默认无格式限制
 52      */
 53     private List<String> fileFormat = new ArrayList<String>();
 54     /**
 55      * HttpServletRequest
 56      */
 57     private HttpServletRequest request;
 58     //私有化无参构造
 59     private FileUpload(){}
 60     
 61     public FileUpload(HttpServletRequest request){
 62         this.request = request;
 63     }
 64     
 65     public FileUpload(String tempPath, String filePath, HttpServletRequest request){
 66         this.request = request;
 67         this.tempPath = tempPath;
 68         this.filePath = filePath;
 69         makeDirectory(tempPath);
 70         makeDirectory(filePath);
 71     }
 72     
 73     /**
 74      * 上传文件
 75      * @return 上传成功返回true
 76      * @throws ProtocolException
 77      * @throws FileUploadException
 78      * @throws NullFileException
 79      * @throws SizeException
 80      * @throws FileFormatException
 81      * @throws IOException
 82      */
 83     public boolean uploadFile() 
 84             throws ProtocolException, NullFileException, SizeException, FileFormatException, IOException, FileUploadException{
 85         boolean b = true;
 86         ServletFileUpload upload = getUpload();
 87         //解析request中的字段,每个字段(上传字段和普通字段)都会自动包装到FileItem中
 88         List<FileItem> fileItems = upload.parseRequest(this.request);
 89         for(FileItem item : fileItems){
 90             //如果为普通字段
 91             if(item.isFormField()){
 92                 continue;
 93             }
 94             //获取文件名
 95             String fileName = item.getName();
 96             //因为IE6得到的是文件的全路径,所以进一步处理
 97             fileName = fileName.substring(fileName.lastIndexOf("\\\\")+1);
 98             //判断上传的文件是否为空
 99             if(item.getSize() <= 0){
100                 b = false;
101                 throw new NullFileException();
102             }
103             //判断文件是否超过限制的大小
104             if(item.getSize() > fileSize*1000){
105                 b = false;
106                 throw new SizeException();
107             }
108             //判断上传文件的格式是否正确
109             if( !isFormat(fileName.substring(fileName.lastIndexOf(".")+1)) ){
110                 b = false;
111                 throw new FileFormatException();
112             }
113             String uuidFileName = getUuidFileName(fileName);
114             //获取文件的输入流
115             InputStream is = item.getInputStream();
116             //创建输出流
117             OutputStream os = new FileOutputStream(this.filePath+"/"+uuidFileName);
118             //输出
119             output(is, os);
120             //将上传文件时产生的临时文件删除
121             item.delete();
122         }
123         return b;
124     }
125     
126     /**
127      * 获取文件上传的输入流
128      * @return
129      * @throws ProtocolException
130      * @throws NullFileException
131      * @throws SizeException
132      * @throws FileFormatException
133      * @throws IOException
134      * @throws FileUploadException
135      */
136     public InputStream getUploadInputStream() 
137             throws ProtocolException, NullFileException, SizeException, FileFormatException, IOException, FileUploadException{
138         ServletFileUpload upload = getUpload();
139         //解析request中的字段,每个字段(上传字段和普通字段)都会自动包装到FileItem中
140         List<FileItem> fileItems = upload.parseRequest(this.request);
141         for(FileItem item : fileItems){
142             //如果为普通字段
143             if(item.isFormField()){
144                 continue;
145             }
146             //获取文件名
147             String fileName = item.getName();
148             //因为IE6得到的是文件的全路径,所以进一步处理
149             fileName = fileName.substring(fileName.lastIndexOf("\\\\")+1);
150             //判断上传的文件是否为空
151             if(item.getSize() <= 0){
152                 throw new NullFileException();
153             }
154             //判断文件是否超过限制的大小
155             if(item.getSize() > fileSize*1000){
156                 throw new SizeException();
157             }
158             //判断上传文件的格式是否正确
159             if( !isFormat(fileName.substring(fileName.lastIndexOf(".")+1)) ){
160                 throw new FileFormatException();
161             }
162             //获取文件的输入流
163             InputStream is = item.getInputStream();
164             
165             return is;
166         }
167         return null;
168     }
169     
170     /**
171      * 获取上传文件的核心
172      * @return ServletFileUpload
173      * @throws ProtocolException 
174      */
175     public ServletFileUpload getUpload() throws ProtocolException{
176         //创建上传文件工厂
177         DiskFileItemFactory factory = new DiskFileItemFactory();
178         //设置内存中缓存区的大小
179         factory.setSizeThreshold(bufferSize);
180         //如果用户未设置上传文件目录,则设置默认目录
181         if(filePath == null){
182             setDefaultFilePath();
183         }
184         //如果用户未设置临时存放目录,则设置默认目录
185         if(tempPath == null){
186             setDefaultTempPath();
187         }
188         //设置上传文件的的临时存放目录
189         factory.setRepository(new File(this.tempPath));
190         //创建上传文件对象[核心]
191         ServletFileUpload upload = new ServletFileUpload(factory);
192         //设置上传文件的编码方式
193         upload.setHeaderEncoding(this.encoding);
194         /*
195          * 判断客户端上传文件是否使用MIME协议
196          * 只有当以MIME协议上传文件时,upload才能解析request中的字段
197          */
198         if(!upload.isMultipartContent(this.request)){
199             throw new ProtocolException();
200         }
201         return upload;
202     }
203     
204     /**
205      * 输出
206      * @param is
207      * @param os
208      * @throws IOException
209      */
210     public void output(InputStream is, OutputStream os) throws IOException{
211         byte[] by = new byte[1024];
212         int len = 0;
213         while( (len = is.read(by)) > 0 ){
214             os.write(by, 0, len);
215         }
216         is.close();
217         os.close();
218     }
219     
220     /**
221      * 判断上传文件的格式是否正确
222      * @param format 文件格式
223      * @return boolean
224      */
225     private boolean isFormat(String format){
226         if(fileFormat.size() == 0){
227             return true;
228         }
229         for(String f : fileFormat){
230             if(f.equalsIgnoreCase(format)){
231                 return true;
232             }
233         }
234         return false;
235     }
236     
237     /**
238      * 返回文件的UUID名,防止文件名重复
239      * @param fileName 文件名
240      * @return uuid名
241      */
242     public String getUuidFileName(String fileName){
243         return UUID.randomUUID().toString()+"#"+fileName;
244     }
245     
246     /**
247      * 设置默认临时目录
248      */
249     private void setDefaultTempPath(){
250         tempPath = filePath+"/temp";
251         
252         makeDirectory(tempPath);
253     }
254     
255     /**
256      * 设置默认文件目录
257      * 默认在D盘
258      */
259     private void setDefaultFilePath(){
260         filePath = "D:/uploadFile";
261         
262         makeDirectory(filePath);
263     }
264     
265     /**
266      * 根据给定的文件目录创建目录
267      * @param filePath
268      */
269     private void makeDirectory(String filePath){
270         File file = new File(filePath);
271         if(!file.exists()){
272             file.mkdir();
273         }
274     }
275     
276     
277     
278     /**
279      * 获取临时目录
280      * @return
281      */
282     public String getTempPath() {
283         return tempPath;
284     }
285     /**
286      * 设置临时目录
287      * @param tempPath
288      */
289     public void setTempPath(String tempPath) {
290         this.tempPath = tempPath;
291         makeDirectory(tempPath);
292     }
293     /**
294      * 获取文件路径
295      * @return
296      */
297     public String getFilePath() {
298         return filePath;
299     }
300     /**
301      * 返回文件路径
302      * @param filePath
303      */
304     public void setFilePath(String filePath) {
305         this.filePath = filePath;
306         makeDirectory(filePath);
307     }
308     /**
309      * 获取内存中缓存区大小
310      * @return
311      */
312     public int getBufferSize() {
313         return bufferSize;
314     }
315     /**
316      * 设置内存中缓存区大小 
317      * 默认100k
318      * @param bufferSize
319      */
320     public void setBufferSize(int bufferSize) {
321         this.bufferSize = bufferSize;
322     }
323     /**
324      * 获取上传文件的最大大小
325      * @return
326      */
327     public int getFileSize() {
328         return fileSize;
329     }
330     /**
331      * 限制上传文件的最大大小,单位为k
332      * 默认1000k
333      * @param fileSize
334      */
335     public void setFileSize(int fileSize) {
336         this.fileSize = fileSize;
337     }
338     /**
339      * 返回上传文件的编码方式
340      * @return
341      */
342     public String getEncoding() {
343         return encoding;
344     }
345     /**
346      * 设置上传文件的编码方式
347      * 默认UTF-8格式
348      * @param encoding
349      */
350     public void setEncoding(String encoding) {
351         this.encoding = encoding;
352     }
353     /**
354      * 获取允许上传文件的格式
355      * @return
356      */
357     public String getFileFormat() {
358         if(fileFormat.size() == 0){
359             return "*";
360         }
361         String format = "";
362         for(String s:fileFormat){
363             format += ","+s;
364         }
365         format = format.substring(format.indexOf(",")+1);
366         return format;
367     }
368     /**
369      * 设置上传文件的格式,多个文件格式则多次调用该方法进行设置
370      * @param fileFormat
371      */
372     public void setFileFormat(String format) {
373         this.fileFormat.add(format);
374     }
375     
376     public HttpServletRequest getRequest() {
377         return request;
378     }
379     
380     public void setRequest(HttpServletRequest request) {
381         this.request = request;
382     }
383     
384 }
复制代码

 

下载文件核心代码

复制代码
  1 package com.lizhou.fileload;
  2 
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.FileNotFoundException;
  6 import java.io.IOException;
  7 import java.io.InputStream;
  8 import java.io.OutputStream;
  9 import java.io.UnsupportedEncodingException;
 10 import java.net.URLEncoder;
 11 import java.util.ArrayList;
 12 import java.util.List;
 13 
 14 import javax.servlet.http.HttpServletRequest;
 15 import javax.servlet.http.HttpServletResponse;
 16 
 17 import com.lizhou.domain.DownloadFile;
 18 import com.lizhou.exception.FileNotExistsException;
 19 
 20 /**
 21  * 下载文件
 22  * @author bojiangzhou
 23  *
 24  */
 25 public class FileDownload {
 26     /**
 27      * 下载时的默认文件目录
 28      */
 29     private String filePath = null;
 30     /**
 31      * 要下载文件的格式
 32      */
 33     private List<String> fileFormat = new ArrayList<String>();
 34     /**
 35      * HttpServletRequest
 36      */
 37     private HttpServletRequest request;
 38     
 39     public FileDownload(HttpServletRequest request){
 40         this.request = request;
 41     }
 42     
 43     public FileDownload(String filePath, HttpServletRequest request){
 44         this.request = request;
 45         this.filePath = filePath;
 46     }
 47     
 48     /**
 49      * 将下载列表绑定到域中
 50      * 默认session
 51      * @param var 域对象变量名
 52      * @throws FileNotExistsException 
 53      */
 54     public void bindDownloadFilesToScope(String var) throws FileNotExistsException{
 55         if(filePath == null){
 56             filePath = "D:/uploadFile";
 57         }
 58         if(!isFileExists(this.filePath)){
 59             throw new FileNotExistsException();
 60         }
 61         List<DownloadFile> list = new ArrayList<DownloadFile>();
 62         getDownloadFiles(filePath, list);
 63         request.getSession().setAttribute(var, list);
 64     }
 65     
 66     /**
 67      * 获得下载目录下的所有文件
 68      * @param filePath
 69      * @param list 
 70      */
 71     private void getDownloadFiles(String filePath, List<DownloadFile> list){
 72         File file = new File(filePath);
 73         if(file.isFile()){
 74             String uuidFileName = file.getName();
 75             if(isFormat(uuidFileName.substring(uuidFileName.lastIndexOf(".")+1))){
 76                 DownloadFile df = new DownloadFile();
 77                 df.setFileName(uuidFileName.substring(uuidFileName.indexOf("#")+1));
 78                 df.setUuidFileName(uuidFileName);
 79                 df.setFilePath(file.getPath());
 80                 list.add(df);
 81             }
 82         } else{
 83             File[] childFiles = file.listFiles();
 84             for(File cf : childFiles){
 85                 getDownloadFiles(cf.getPath(), list);
 86             }
 87         }
 88     }
 89     
 90     /**
 91      * 下载文件
 92      * @param var 下载列表的域变量名
 93      * @param uuidFileName 客户端传来的文件的uuid名
 94      * @param response
 95      * @throws IOException
 96      */
 97     public void downloadFile(String var, String uuidFileName, HttpServletResponse response) throws IOException{
 98         byte[] by = uuidFileName.getBytes("ISO-8859-1");
 99         uuidFileName = new String(by, "UTF-8");
100         List<DownloadFile> files = (List<DownloadFile>) this.request.getSession().getAttribute(var);
101         for(DownloadFile file : files){
102             if(file.getUuidFileName().equals(uuidFileName)){
103                 InputStream is = new FileInputStream(file.getFilePath());
104                 OutputStream os = response.getOutputStream();
105                 response.setHeader("Content-Disposition", "attachment; filename="+URLEncoder.encode(file.getFileName(), "UTF-8"));
106                 output(is, os);
107                 break;
108             }
109         }
110     }
111     
112     public void output(InputStream is, OutputStream os) throws IOException{
113         byte[] by = new byte[1024];
114         int len = 0;
115         while( (len = is.read(by)) > 0 ){
116             os.write(by, 0, len);
117         }
118         is.close();
119         os.close();
120     }
121     
122     /**
123      * 判断文件的格式是否正确
124      * @param format 文件格式
125      * @return boolean
126      */
127     private boolean isFormat(String format){
128         if(fileFormat.size() == 0){
129             return true;
130         }
131         for(String f : fileFormat){
132             if(f.equalsIgnoreCase(format)){
133                 return true;
134             }
135         }
136         return false;
137     }
138     
139     /**
140      * 判断文件目录是否存在
141      * @param filePath 文件目录
142      * @return boolean
143      */
144     private boolean isFileExists(String filePath){
145         boolean b = true;
146         File file = new File(filePath);
147         if(!file.exists()){
148             b = false;
149         }
150         return b;
151     }
152 
153     public String getFilePath() {
154         return filePath;
155     }
156     
157     /**
158      * 设置下载路径
159      * @param filePath
160      * @throws FileNotExistsException
161      */
162     public void setFilePath(String filePath) {
163         this.filePath = filePath;
164     }
165     
166     /**
167      * 获取允许上传文件的格式
168      * @return
169      */
170     public String getFileFormat() {
171         if(fileFormat.size() == 0){
172             return "*";
173         }
174         String format = "";
175         for(String s:fileFormat){
176             format += ","+s;
177         }
178         format = format.substring(format.indexOf(",")+1);
179         return format;
180     }
181     /**
182      * 设置上传文件的格式,多个文件格式则多次调用该方法进行设置
183      * @param fileFormat
184      */
185     public void setFileFormat(String format) {
186         this.fileFormat.add(format);
187     }
188 
189     public HttpServletRequest getRequest() {
190         return request;
191     }
192 
193     public void setRequest(HttpServletRequest request) {
194         this.request = request;
195     }
196     
197 }
复制代码

 

注:上传文件时,前台form表单一定要有如下属性:enctype="multipart/form-data"

 

 

附上源码+导出的jar包+使用demo:下载文件

 

以上是关于java文件上传下载的主要内容,如果未能解决你的问题,请参考以下文章

如何在片段中使用 GetJsonFromUrlTask​​.java

完全下载文件时,将下载的文件从一个片段传递到另一个片段

Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”

VSCode创建自定义用户片段

从JVM的角度看JAVA代码--代码优化

nzSQLException 读取超时错误