文章目录
- 设想场景
- 实现流程
- 小结
设想场景
为方便老师录入大量学生图片信息,在添加照片时,学生的相关资料以身份证号码+图片描述命名如
(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"));// 转成 名字对应文件流的mapfileMap = 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项目中实现资料包的导入读取并导出压缩包,加强文件读写的能力 冲!!!。