Back-end/Java

[JAVA] 기존 경로에 담겨있는 파일들 Zip 파일 만들기

Rowen Jobs 2023. 2. 20. 22:48
728x90
반응형

오늘은 작년 11월 쯤 개발에 필요한 기능이였던 Zip 파일 만드는 방법을 공유한다! 

 

우선 기능을 설명하자면 최신 업로드 된 파일들을 모아 zip 형태로 다운로드를 받아야 한다. 

고려해야 할 점.

1. 업로드 된 파일이 없는 경우

2. zip 파일을 다운받는 경로에 동일한 zip 파일명을 가진 경우 

 

그럼 설명 시작!

우선 기본적인 필요한 변수들을 선언해준다.

   // zip 기능 사용 
   ZipOutputStream zout = null;
   String zipName = "zip파일명.zip";
   String tempPath = "";
   String contentType = null; 
   String noSuchFileName = "";
   List<String> chk = new ArrayList<>();
   
   List<FileModel> uploadFiles = /*기존 시스템에 등록되어 있는 파일경로, 파일이름 */

위와 같이 변수들을 선언해주고 uploadFiles 같은 경우는 시스템에 등록되어 있는 파일(zip 파일을 만들려고 하는 파일들의 경로들)들의 경로와 파일 오리지널 명의 정보를 가지고 온다. 

   // 기존 업로드 된 파일 경로를 불러왔을 때 있을 경우 If 문 실행
   if(uploadFiles.size() > 0) {
      try {
         byte[] buffer = new byte[1024];
         FileInputStream in = null;
         // zip 파일 만들 경로
         zout = new ZipOutputStream(new FileOutputStream("/D:/temp/" + zipName));
         
         // File 갯수만큼 for 문 실행
         for(int i = 0; i < uploadFiles.size(); i++) {
         	// temp 경로에 upload 된 파일 경로를 담아줍니다. 
            tempPath = uploadFiles.get(i).getFile_path();
            
            // 실제 파일이 있는지 체크
            File file = new java.io.File(tempPath + "/" + uploadFiles.get(i).getOrg_file_name());
            if(file.exists()) {
               // 중복되는 파일 파일명 변경
               String fileName = uploadFiles.get(i).getOrg_file_name();
               
               // 확장자 split 처리
               String[] fileNameList = fileName.split("\\.");

		// 중복되는 파일명 뒤 숫자 처리 변수 선언
               int count = 2;

               in = new FileInputStream(tempPath + "/" + uploadFiles.get(i).getOrg_file_name());
               
               for(int j = 0; j < chk.size(); j++) {
               		// 이전 chk 배열에 담긴 파일명과 동일 시 파일명 중복작업 처리
                  if(chk.get(j).equals(uploadFiles.get(i).getOrg_file_name())) {
                     fileName = (fileNameList[0]) + "_(" + count + ")" + "." + (fileNameList[1]);
                     count++;
                  }; 
               }
               
               // 다음 파일명과 비교를 위해 현재 돌아가는 인덱스의 파일명을 chk 배열에 담는다.
               chk.add(fileName);
               
               zout.putNextEntry(new ZipEntry(fileName));
               int len;
               while((len = in.read(buffer)) > 0){
                  zout.write(buffer, 0, len);          //읽은 파일을 ZipOutputStream에 Write
               }
            }else {
		// 파일이 없을 경우 String 배열에 담아준다 -> 에러 발생 MSG
               noSuchFileName += ", " + uploadFiles.get(i).getOrg_file_name() + "<br>";
            }
                
                zout.closeEntry();
                
                // null 인데 닫을 경우 에러 발생
                if(in != null) {
                   in.close();
                }
         }
         
         // 파일 없는 경우 강제에러 발생. 
         if(!noSuchFileName.equals("")) {
            throw new Exception("파일이 없습니다. <br>" + noSuchFileName);
         }
            
          zout.close();
             //ZIP파일 압축 END
          
             Path filePath = Paths.get("/D:/temp/");
             Path file = filePath.resolve(zipName);
             
             String org_file_name = new String(zipName.getBytes("UTF-8"), "ISO-8859-1");
             
             Resource resource = new UrlResource(file.toUri());
             contentType = req.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
             
             if(resource.exists()) {
                 return ResponseEntity.ok()
                         .contentType(MediaType.parseMediaType(contentType))
                         .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""+ org_file_name + "\"")
                         .body(resource);
             }
      }catch(IOException ex){
         ex.printStackTrace();
          }finally{
             if (zout != null){
                zout = null;
            }
   }
   
   }

위와 같이 파일들이 담겨있는 경로를 for 문을 사용하여 담아주고 zip 파일로 out 해주면 된다!

 

* 공부를 하면서 구글링 하며 작업한 내용이라 틀린 부분이 있으면 댓글 부탁드립니다*

728x90