设想场景
为方便老师录入大量学生图片信息,在添加照片时,学生的相关资料以身份证号码+图片描述命名如
(1231231234567+一寸照片.jpg)
(1231231234567+身份证正面照片.jpg)
(1231231234567+身份证背面照片.jpg)
(1231231234567+毕业证照片.jpg)
(1231231233123+学位证照片.jpg)
压缩zip后上传保存学生资料
并实现后续可下载指定学生的资料包。
实现流程
就是一读写操作。
下面是代码实现
@PostMapping("/importZip")
public void importZip(MultipartFile file) {
studentService.importZip(file);
}
import org.springframework.mock.web.MockMultipartFile;
public void importZip(MultipartFile file) {
Map<String, MultipartFile> fileMap = new HashMap<>();
try {
// 获取zip文件输入流
ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream(), Charset.forName("GBK"));
// 转成 名字对应文件流的map
fileMap = convertToMultipartFile(zipInputStream);
for (Map.Entry<String, MultipartFile> stringFileEntry : fileMap.entrySet()) {
// 上传并返回新文件名称
// 上传这块走自己的接口咯、目的是上传图片后获取url保存起来
String url = FileUploadUtils.upload(filePath, stringFileEntry.getValue());
}
}catch (Exception e){
e.printStackTrace();
}
}
public static Map<String, MultipartFile> convertToMultipartFile(ZipInputStream zipInputStream) throws IOException {
Map<String, MultipartFile> result = new HashMap<>();
// 读取zip文件中的条目
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
if (!zipEntry.isDirectory()) {
byte[] bytes = readAllBytesFromZipInputStream(zipInputStream);
// 创建MockMultipartFile并返回
result.put(zipEntry.getName(), new MockMultipartFile(zipEntry.getName(), zipEntry.getName(),"", new ByteArrayInputStream(bytes)));
zipInputStream.closeEntry();
}
zipEntry = zipInputStream.getNextEntry();
}
zipInputStream.close();
return result;
}
public static byte[] readAllBytesFromZipInputStream(ZipInputStream zipInputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = zipInputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
return byteArrayOutputStream.toByteArray();
}
好的、上面的代码可以实现导入zip并且把压缩包里的文件名和文件流一一返回给你了。
你只需要把文件流调上传你的接口、并把文件名和url存下来,后面会用到。
下面我们来说说、正面把上传的文件、压缩成zip 导出。
public void download(HttpServletResponse response, String studentId) {
//!!!把你的资料获取出来!!!
List<String> imageUrls = null;
//!!!把你的资料获取出来!!!
// 创建一个临时文件夹,用于存放下载的图片
File tempFolder = new File("/newFile");
tempFolder.mkdirs();
try {
// 遍历图片URL列表,下载并压缩图片
for (String imageUrl : imageUrls) {
try (BufferedInputStream in = new BufferedInputStream(bufferedReader(imageUrl));
FileOutputStream fileOutputStream = new FileOutputStream(tempFolder.getPath() + "/" + imageUrl.substring(imageUrl.lastIndexOf("/") + 1))) {
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
fileOutputStream.write(dataBuffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 创建临时压缩文件
File zipFile = File.createTempFile("相关资料", ".zip");
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
// 压缩文件夹内的文件
File folder = new File(tempFolder.getPath());
compressFolder(folder, zos);
// 关闭流
zos.close();
fos.close();
// 设置响应头
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFile.getName() + ".zip\"");
// 将压缩文件写入响应输出流
FileInputStream fis = new FileInputStream(zipFile);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = response.getOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
bis.close();
fis.close();
os.flush();
os.close();
// 删除临时压缩文件
zipFile.delete();
} catch (IOException e) {
e.printStackTrace();
} finally {
//删除临时文件夹及其文件
deleteFolder(tempFolder);
}
}
public InputStream bufferedReader(String url) throws IOException {
//!!!!设置超时时间、不然遇到偶发性的url失效找不到图片就会直接报错、后面都不走了!!!
URL downloadUrl = new URL(urlEncodeChinese(url));
HttpURLConnection httpURLConnection = (HttpURLConnection) downloadUrl.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setUseCaches(false);
//设置超时时间
httpURLConnection.setConnectTimeout(1000);
httpURLConnection.setReadTimeout(1000);
return httpURLConnection.getInputStream();
}
// 递归删除文件夹及其文件
private void deleteFolder(File folder) {
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
deleteFolder(file);
} else {
file.delete();
}
}
}
folder.delete();
}
小结
本篇文章 就是解决 在Java项目中实现资料包的导入读取并导出压缩包,加强文件读写的能力 冲!!!。