业务需求:上传压缩包,对压缩包中的文件进行批量上传处理
- 读取原压缩包文件,解压缩至临时目录
-
对临时目录中的解压缩文件进行批量上传处理
-
删除临时目录及其下的文件
首先前台上传zip格式的压缩文件到后台 进行解压
/**
* 解压到目标路径
*
* @param srcFile 文件
* @param savePath 目标路径
* @return
*/
public static void unZip(MultipartFile srcFile, String savePath) throws RuntimeException {
FileOutputStream out = null;
BufferedOutputStream bos = null;
try {
File file = null;
InputStream ins = srcFile.getInputStream();
File file2 = new File(savePath);
if (!file2.exists()) {
file2.mkdirs();//创建目录
}
file = new File(savePath + srcFile.getOriginalFilename());
inputStreamToFile(ins, file);
if (!file.exists()) {
throw new RuntimeException(file.getPath() + ",file is not found");
}
//读取压缩文件
ZipInputStream in = new ZipInputStream(new FileInputStream(file), Charset.forName("GBK"));
//zip文件实体类
ZipEntry entry;
//遍历压缩文件内部 文件数量
while ((entry = in.getNextEntry()) != null) {
if (!entry.isDirectory()) {
//文件输出流
out = new FileOutputStream(savePath + entry.getName());
bos = new BufferedOutputStream(out);
int len;
byte[] buf = new byte[1024];
while ((len = in.read(buf, 0, 1024)) != -1) {
bos.write(buf, 0, len);
}
bos.close();
out.flush();
out.close();
}
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[512];
while ((bytesRead = ins.read(buffer, 0, 512)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("文件读写错误:", e);
}
}
将压缩文件解压到目标目录,后续获取该路径下所有的文件,进行上传处理;
解压时注意要先判断文件路径是否存在,不存在则创建 (事先在服务器上创建路径 没生效 找不到路径)
一定要把所有的流全部关闭 不关闭会导致文件删除失败
/**
* 获取路径下所有的文件
*
* @param savePath 目标路径
* @return
*/
public List<File> getSubFiles(String savePath) {
List<File> fileList = new ArrayList<>();
File file = new File(savePath);
File[] files = file.listFiles();
for (File fileIndex : files) {
if (!fileIndex.exists()) {
throw new NullPointerException("Cannot find " + fileIndex);
} else if (fileIndex.isFile()) {
fileList.add(fileIndex);
} else {
if (fileIndex.isDirectory()) {
getSubFiles(fileIndex.getAbsolutePath());
}
}
}
return fileList;
}
如果上传时 文件名称有非法字符 可以进行非法字符处理
/**
* 将匹配到的非法字符以空替换
*
* @param fileName 获取的文件名
* @return
*/
public String illegalCharacterHandling(String fileName) {
Pattern pattern = Pattern.compile("[\\s\\\\/:\\*\\?\\\"<>\\|]");
Matcher matcher = pattern.matcher(fileName);
return matcher.replaceAll("");
}
删除文件处理
/**
* 删除路径及路径下所有文件
*
* @param savePath 路径
* @return
*/
public static void clearFiles(String savePath) {
File file = new File(savePath);
deleteFile(file);
}
public static void deleteFile(File file) {
if (file.exists()) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
deleteFile(files[i]);
}
}
}
file.delete();
}
最后将List<File> 上传到文件服务器即可
注意的是这里的路径如果是固定路径的话,并发的情况下会导致文件上传重复或者文件上传失败等情况