开发中过程中遇到这样一个需求,所有的文件按照不同的等级分别归档到不同的文件夹中,然后下载。
开发思路
- 将文件按照不同等级封装到服务器上的临时的一个文件夹中。
- 把文件夹压缩成.zip
- 下载 .zip 文件
- 删除服务器上的临时文件
代码实现
1、创建文件工具类
public class FileUtils {
private static final int BUFFER_SIZE = 2 * 1024;
}
2、第一个方法 (创建一个临时目录)
/**
* @return suffix 目录名称 pathName 目录根路径
* @Date 2021/6/30 14:11Direc
* @Author jiangheng
* @Description //TODO 创建一个临时目录
**/
public static java.nio.file.Path createDirectory(String suffix, String pathName) {
java.nio.file.Path path1 = Paths.get(pathName + "/" + suffix);
//判断目录是否存在
boolean pathExists = Files.exists(path1, new LinkOption[]{LinkOption.NOFOLLOW_LINKS});
if (pathExists) {
return path1;
}
try {
path1 = Files.createDirectory(path1);
} catch (IOException e) {
e.printStackTrace();
}
return path1;
}
3、赋值文件
/**
* @return OriginalPathName 源文件 path 目标文件地址 pathName 根目录
* @Date 2021/6/30 15:11
* @Author jiangheng
* @Description //TODO 复制文件
**/
public static void copyFile(String OriginalPathName, java.nio.file.Path path, String pathName) {
java.nio.file.Path originalPath = Paths.get(pathName + "/" + OriginalPathName);
try {
Files.copy(originalPath, path,
StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
}
4、向目录中添加文件
/**
* @return attachments 这个参数主要是从数据库中获取文件的信息,这里可以根据自己的需求更改
* @Date 2021/6/30 17:31
* @Author jiangheng
* @Description //TODO 向文件夹中添加文件
**/
public static void addFile(List<Attachment> attachments, String path, String pathName) {
//遍历所有的文件
int i = 0;
for (Attachment attachment : attachments) {
i++;
String type = "." + attachment.getFileType();
java.nio.file.Path targetPath = Paths.get(path + i + type);
copyFile(attachment.getFilePath(), targetPath, pathName);
}
}
5、压缩目录
public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException {
long start = System.currentTimeMillis();
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(out);
File sourceFile = new File(srcDir);
compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) + " ms");
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils", e);
} finally {
if (zos != null) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6、递归压缩
public static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure)
throws Exception {
byte[] buf = new byte[BUFFER_SIZE];
if (sourceFile.isFile()) {
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
zos.putNextEntry(new ZipEntry(name));
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
// Complete the entry
zos.closeEntry();
in.close();
} else {
File[] listFiles = sourceFile.listFiles();
if (listFiles == null || listFiles.length == 0) {
// 需要保留原来的文件结构时,需要对空文件夹进行处理
if (KeepDirStructure) {
// 空文件夹的处理
zos.putNextEntry(new ZipEntry(name + "/"));
// 没有文件,不需要文件的copy
zos.closeEntry();
}
} else {
for (File file : listFiles) {
// 判断是否需要保留原来的文件结构
if (KeepDirStructure) {
// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
} else {
compress(file, zos, file.getName(), KeepDirStructure);
}
}
}
}
}
7、 下载zip
/**
* 下载文件流
* @param response
* @param fileName
* @param inputData
* @throws IOException
*/
public static void downloadFile(HttpServletResponse response, String fileName, InputStream inputData) throws IOException {
BufferedInputStream bins = new BufferedInputStream(inputData);//放到缓冲流里面
OutputStream outs = response.getOutputStream();//获取文件输出IO流
BufferedOutputStream bouts = new BufferedOutputStream(outs);
response.setContentType("application/x-download");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
int bytesRead = 0;
byte[] buffer = new byte[8192];
//开始向网络传输文件流
while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {
bouts.write(buffer, 0, bytesRead);
}
bouts.flush();//这里一定要调用flush()方法
inputData.close();
bins.close();
outs.close();
bouts.close();
}
8、删除临时的.zip文件
public static void deleteFile(File file) {
if (file.isDirectory()) {
File[] subFiles = file.listFiles();
if (subFiles != null) {
for (File subFile : subFiles) {
deleteFile(subFile);
}
}
if (file.exists())
file.delete(); // 删除文件夹
} else {
if (file.exists())
file.delete();
}
}
9 、删除临时的目录和文件
/**
* @return
* @Date 2021/7/1 14:55
* @Author jiangheng
* @Description //TODO 删除目录及文件
**/
public static void deleteDirAndFiles(File file) {
File[] files = file.listFiles();
if (files != null && files.length > 0) {
for (File f : files) {
deleteDirAndFiles(f);
}
}
file.delete();
System.out.println("删除成功" + file.getName());
}
版权声明:本文为weixin_43610698原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。