我们有两种方式:
1.递归操作文件(不提议使用,因为递归太耗空间资源,所以递归容易造成栈内存溢出)
2.接住队列来操作文件下载
在这里使用第二种方式:
1.得到根目录
2.将更目录添加到队列中
3.判断目录是否空目录
如果是空目录,无理采
如果该目录中文件,就将该目录从队列中删除,并得到该目录的引用,得到该目录中的文件,然后遍历显示即可
队列的方法:
add(E,e)返回boolean类型 将指定的元素导此队列中,如果可以立即执行此操作,而不会违反容量限制,true在成功后 返 回 IllegalStateExceotion 如果当前没有可用空间,则抛出 IllegalStateExceotion
element( )返回E 检索,但不删除,这个队列头
peek() 返回E 检索并删除此队列的头,如果次队列为空,则返回null
offer(E e)返回boolean 如果在不违反容量限制的情况下立即执行,则将指定的元素输入到此队列中
poll() 返回E 检索并删除此队列的头,如果队列为空,则返回null
remove() 返回E 检索并删除队列的头
<%@page import="org.apache.jasper.tagplugins.jstl.core.ForEach"%>
<%@page import="java.util.Queue"%>
<%@page import="java.util.LinkedList"%>
<%@page import="java.io.File"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%-- <a href="${pageContext.request.contextPath }/dwonloadFiles?path=本地磁盘文件名">文件名</a>
--%>
<%
//根目录
File file=new File("D:/upload");
//创建队列对象
Queue<File> queue= new LinkedList<File>();
//将目录添加到队列中
queue.add(file);
//循环判断队列是否为空,如果不为空,说明该队列中有文件
while(!queue.isEmpty()){
//队列不为空,将队列中的文件踢出队列
File file1=queue.poll();
File[] files=file1.listFiles();
for(File file2:files){
//是否是文件
if( file2.isFile()){
//将文件的路径作为下载路径,将文件名作为下载名称
String str="<a href='${${pageContext.request.contextPath }/dwonloadFiles?path="+file2.getAbsolutePath()+"'>"+file2.getName()+"</a><br>";
out.write(str);
}else{
//目录,再次添加对列出
queue.offer(file2);
}
}
}
%>
</body>
</html>
Servlet代码
//得到文件路径
String path = request.getParameter("path");
//截取路劲得到文件名
String filename = path.substring(path.lastIndexOf("\\")+1);
System.out.println(filename);
//给响应头设置一个文件类型
// String realpath = getServletContext().getRealPath(filename);
String mimeType = getServletContext().getMimeType(filename);
response.setContentType(mimeType);
// response.setHeader("Content-Type", getServletContext().getMimeType(filename));
//浏览器的种类,解决赢浏览器的编码的乱码问题
String web = request.getHeader("User-Agent");
System.out.println(web);
if(web.contains("MSIE")){
filename = URLEncoder.encode(filename);
}else if(web.contains("Firefox")){
filename = base64EncodeFileName(filename);
}else if(web.contains("Chrome")){
filename = new String(filename.getBytes("utf-8"),"ISO-8859-1");
}
//让能被浏览器解析的文件,不能解析
response.setHeader("Content-Disposition", "attachment;filename="+filename);
FileInputStream fis = new FileInputStream(path);
ServletOutputStream os = response.getOutputStream();
byte[] b=new byte[1024*8];
int len=0;
while((len=fis.read(b))!=-1){
os.write(b, 0, len);
}
fis.close();
}
/*
* 火狐浏览器下载时的中文乱码问题
*/
public String base64EncodeFileName(String fileName) {
BASE64Encoder base64Encoder = new BASE64Encoder();
try {
return "=?UTF-8?B?"
+ new String(base64Encoder.encode(fileName
.getBytes("UTF-8"))) + "?=";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}