文章目錄
- 設想場景
- 實現流程
- 小結
設想場景
為方便老師錄入大量學生圖片信息,在添加照片時,學生的相關資料以身份證號碼+圖片描述命名如
(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項目中實現資料包的導入讀取并導出壓縮包,加強文件讀寫的能力 沖!!!。