一、前言
程序员在做web等项目的时候,往往都需要添加文件上传、下载、删除的功能,有时是单文件,有时多文件批量 操作,而这些功能的代码程序员可以自己收藏起来当成工具使用,这样,程序员在进行程序设计的时候就会事半功倍 了,那么接下来的博客将会介绍各个框架的文件上传和下载功能的使用方法。
这篇博客的重点放在各个框架都能适用的文件下载功能代码,话不多说,直接切入主题:
二、实例
1.一般需要加入的jar包:
commons.fileupload-1.2.1.jar和commons.io-1.4.0.jar,点击下载jar包
2.方法实例:
<span style="color:#000000"><code> <span style="color:#880000">//普通java文件下载方法,适用于所有框架 </span>
<span style="color:#000088">public</span> String downloadFilesTest(HttpServletRequest request,HttpServletResponse res) throws IOException {
<span style="color:#880000">//获取文件根目录,不同框架获取的方式不一样,可自由切换 </span>
String basePath = request.getSession().getServletContext().getRealPath(<span style="color:#009900">"/upload/fileDir"</span>);
<span style="color:#880000">//获取文件名称(包括文件格式) </span>
String fileName = <span style="color:#009900">"1.jpg"</span>;
<span style="color:#880000">//组合成完整的文件路径 </span>
String targetPath = basePath+File.separator+fileName;
<span style="color:#880000">//模拟多一个文件,用于测试多文件批量下载 </span>
String targetPath1 = basePath+File.separator+<span style="color:#009900">"2.jpg"</span>;
<span style="color:#880000">//模拟文件路径下再添加个文件夹,验证穷举</span>
String targetPath2 = basePath+File.separator+<span style="color:#009900">"test"</span>;
System.out.println(<span style="color:#009900">"文件名:"</span>+fileName);
System.out.println(<span style="color:#009900">"文件路径:"</span>+targetPath);
<span style="color:#880000">//方法1:IO流实现下载的功能 </span>
res.setContentType(<span style="color:#009900">"text/html; charset=UTF-8"</span>); <span style="color:#880000">//设置编码字符 </span>
res.setContentType(<span style="color:#009900">"application/octet-stream"</span>); <span style="color:#880000">//设置内容类型为下载类型 </span>
res.setHeader(<span style="color:#009900">"Content-disposition"</span>, <span style="color:#009900">"attachment;filename="</span>+fileName);<span style="color:#880000">//设置下载的文件名称 </span>
OutputStream out = res.getOutputStream(); <span style="color:#880000">//创建页面返回方式为输出流,会自动弹出下载框 </span>
/* <span style="color:#880000">//方法1-1:IO字节流下载,用于小文件 </span>
System.out.println(<span style="color:#009900">"字节流下载"</span>);
InputStream is = <span style="color:#000088">new</span> FileInputStream(targetPath); <span style="color:#880000">//创建文件输入流 </span>
byte[] Buffer = <span style="color:#000088">new</span> byte[<span style="color:#006666">2048</span>]; <span style="color:#880000">//设置每次读取数据大小,即缓存大小 </span>
int size = <span style="color:#006666">0</span>; <span style="color:#880000">//用于计算缓存数据是否已经读取完毕,如果数据已经读取完了,则会返回-1 </span>
<span style="color:#000088">while</span>((size=is.read(Buffer)) != -<span style="color:#006666">1</span>){ <span style="color:#880000">//循环读取数据,如果数据读取完毕则返回-1 </span>
out.write(Buffer, <span style="color:#006666">0</span>, size); <span style="color:#880000">//将每次读取到的数据写入客户端 </span>
}
is.close();
*/
/* <span style="color:#880000">//方法1-2:IO字符流下载,用于大文件 </span>
System.out.println(<span style="color:#009900">"字符流"</span>);
File file = <span style="color:#000088">new</span> File(targetPath); <span style="color:#880000">//创建文件 </span>
FileInputStream fis=<span style="color:#000088">new</span> FileInputStream(file); <span style="color:#880000">//创建文件字节输入流 </span>
BufferedInputStream bis=<span style="color:#000088">new</span> BufferedInputStream(fis); <span style="color:#880000">//创建文件缓冲输入流 </span>
byte[] buffer = <span style="color:#000088">new</span> byte[bis.available()];<span style="color:#880000">//从输入流中读取不受阻塞</span>
bis.read(buffer);<span style="color:#880000">//读取数据文件</span>
bis.close();
out.write(buffer);<span style="color:#880000">//输出数据文件</span>
out.flush();<span style="color:#880000">//释放缓存</span>
out.close();<span style="color:#880000">//关闭输出流</span>
*/
/* <span style="color:#880000">//方法1-3:将附件中多个文件进行压缩,批量打包下载文件 </span>
<span style="color:#880000">//创建压缩文件需要的空的zip包 </span>
String zipBasePath=request.getSession().getServletContext().getRealPath(<span style="color:#009900">"/upload/zip"</span>);
String zipName = <span style="color:#009900">"temp.zip"</span>;
String zipFilePath = zipBasePath+File.separator+zipName;
<span style="color:#880000">//创建需要下载的文件路径的集合</span>
List<String> filePaths = <span style="color:#000088">new</span> ArrayList<String>();
filePaths.add(targetPath);
filePaths.add(targetPath1);
filePaths.add(targetPath2);
<span style="color:#880000">//压缩文件</span>
File zip = <span style="color:#000088">new</span> File(zipFilePath);
<span style="color:#000088">if</span> (!zip.exists()){
zip.createNewFile();
}
<span style="color:#880000">//创建zip文件输出流 </span>
ZipOutputStream zos = <span style="color:#000088">new</span> ZipOutputStream(<span style="color:#000088">new</span> FileOutputStream(zip));
this.zipFile(zipBasePath,zipName, zipFilePath,filePaths,zos);
zos.close();
res.setHeader(<span style="color:#009900">"Content-disposition"</span>, <span style="color:#009900">"attachment;filename="</span>+zipName);<span style="color:#880000">//设置下载的压缩文件名称</span>
<span style="color:#880000">//将打包后的文件写到客户端,输出的方法同上,使用缓冲流输出 </span>
BufferedInputStream bis = <span style="color:#000088">new</span> BufferedInputStream(<span style="color:#000088">new</span> FileInputStream(zipFilePath));
byte[] buff = <span style="color:#000088">new</span> byte[bis.available()];
bis.read(buff);
bis.close();
out.write(buff);<span style="color:#880000">//输出数据文件</span>
out.flush();<span style="color:#880000">//释放缓存</span>
out.close();<span style="color:#880000">//关闭输出流</span>
*/
<span style="color:#000088">return</span> <span style="color:#000088">null</span>;
}
/**
* 压缩文件
* @param zipBasePath 临时压缩文件基础路径
* @param zipName 临时压缩文件名称
* @param zipFilePath 临时压缩文件完整路径
* @param filePaths 需要压缩的文件路径集合
* @throws IOException
*/
<span style="color:#000088">private</span> String zipFile(String zipBasePath, String zipName, String zipFilePath, List<String> filePaths,ZipOutputStream zos) throws IOException {
<span style="color:#880000">//循环读取文件路径集合,获取每一个文件的路径 </span>
<span style="color:#000088">for</span>(String filePath : filePaths){
File inputFile = <span style="color:#000088">new</span> File(filePath); <span style="color:#880000">//根据文件路径创建文件 </span>
<span style="color:#000088">if</span>(inputFile.exists()) { <span style="color:#880000">//判断文件是否存在 </span>
<span style="color:#000088">if</span> (inputFile.isFile()) { <span style="color:#880000">//判断是否属于文件,还是文件夹 </span>
<span style="color:#880000">//创建输入流读取文件 </span>
BufferedInputStream bis = <span style="color:#000088">new</span> BufferedInputStream(<span style="color:#000088">new</span> FileInputStream(inputFile));
<span style="color:#880000">//将文件写入zip内,即将文件进行打包 </span>
zos.putNextEntry(<span style="color:#000088">new</span> ZipEntry(inputFile.getName()));
<span style="color:#880000">//写入文件的方法,同上 </span>
int size = <span style="color:#006666">0</span>;
byte[] buffer = <span style="color:#000088">new</span> byte[<span style="color:#006666">1024</span>]; <span style="color:#880000">//设置读取数据缓存大小</span>
<span style="color:#000088">while</span> ((size = bis.read(buffer)) > <span style="color:#006666">0</span>) {
zos.write(buffer, <span style="color:#006666">0</span>, size);
}
<span style="color:#880000">//关闭输入输出流 </span>
zos.closeEntry();
bis.close();
} <span style="color:#000088">else</span> { <span style="color:#880000">//如果是文件夹,则使用穷举的方法获取文件,写入zip </span>
<span style="color:#000088">try</span> {
File[] files = inputFile.listFiles();
List<String> filePathsTem = <span style="color:#000088">new</span> ArrayList<String>();
<span style="color:#000088">for</span> (File fileTem:files) {
filePathsTem.add(fileTem.toString());
}
<span style="color:#000088">return</span> zipFile(zipBasePath, zipName, zipFilePath, filePathsTem,zos);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
<span style="color:#000088">return</span> <span style="color:#000088">null</span>;
} </code></span>
三、总结
1. 该方法结合了字节流、字符流进行单文件和多文件打包下载,方法1-1、方法1-2和方法1-3分别属于不同形式的下载方法,都是在方法1的基础之上进行的操作,三种方法不可同时使用,需要使用哪种类型的方法则去掉注释即可;
2、实践是检验认识真理性的唯一标准,根据代码和注释多进行尝试,则很快就会明白其中的原理
上一篇:jfinal的绝对路径和action请求路径添加文件夹名称而导致”404 not found”的问题
下一篇: ssh框架之springmvc文件下载功能代码