2017-11-15 19 views
0

ZIP 파일 내에 ZIP 파일을 만들어 Java에서 얻은 이전의 메모리 우편 구조를 재구성하려고합니다.Java에서 ZIP 파일로 ZIP 파일을 만드는 방법

초기 ZIP 파일 내부에서 생성 된 내부 ZIP에 오류가 발생하여 실패합니다. 파일이 손상되었습니다. 파일을 열려고 할 때 "예기치 않은 파일 끝"이이됩니다. 코드가 자바 스택과지도를 사용하여 메모리에 모든 압축을 해제

-input.zip --innerInput.zip

:

나는이 구조를 얻었다. 그런 다음 innerInput.zip과 함께 input2.zip을 만듭니다.

요약 : 전체적으로 메모리에 ZIP이있는 ZIP을 만들어야합니다 (디스크에 일시적으로 저장하지 않음).

CODE : 나에게

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.util.ArrayDeque; 
import java.util.ArrayList; 
import java.util.Deque; 
import java.util.HashMap; 
import java.util.LinkedHashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.SortedMap; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipInputStream; 

import org.apache.commons.lang3.StringUtils; 

public class ZipHandler1 { 

    private static final int BUFFER_SIZE = 2048; 

    private static final String ZIP_EXTENSION = ".zip"; 
    public static final Integer FOLDER = 1; 
    public static final Integer ZIP = 2; 
    public static final Integer FILE = 3; 


    public static Deque<Map<Integer, Object[]>> unzip(ByteArrayOutputStream zippedOutputFile) { 

     try { 

      ZipInputStream inputStream = new ZipInputStream(
      new BufferedInputStream(new ByteArrayInputStream(
       zippedOutputFile.toByteArray()))); 

      ZipEntry entry; 

      Deque<Map<Integer, Object[]>> result = new ArrayDeque<Map<Integer, Object[]>>(); 

      while ((entry = inputStream.getNextEntry()) != null) { 

       LinkedHashMap<Integer, Object[]> map = new LinkedHashMap<Integer, Object[]>(); 
       ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
       System.out.println("\tExtracting entry: " + entry); 
       int count; 
       byte[] data = new byte[BUFFER_SIZE]; 
       if (!entry.isDirectory()) { 
        BufferedOutputStream out = new BufferedOutputStream(
      outputStream, BUFFER_SIZE); 

       while ((count = inputStream.read(data, 0, BUFFER_SIZE)) != -1) { 
        out.write(data, 0, count); 
       } 

       out.flush(); 
       out.close(); 

       // recursively unzip files 
       if (entry.getName().toUpperCase().endsWith(ZIP_EXTENSION.toUpperCase())) { 
       map.put(ZIP, new Object[] {entry.getName(), unzip(outputStream)}); 
       result.add(map); 

       } else { 
        map.put(FILE, new Object[] {entry.getName(), outputStream}); 
        result.add(map); 
       } 
       } else { 
        map.put(FOLDER, new Object[] {entry.getName(), 
        unzip(outputStream)}); 
        result.add(map); 
       } 
      } 

     inputStream.close(); 

     return result; 

     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

package course.hernan; 

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.util.ArrayDeque; 
import java.util.Deque; 
import java.util.LinkedHashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipInputStream; 
import java.util.zip.ZipOutputStream; 

import org.apache.commons.io.IOUtils; 

public class FileReader { 

    private static final int BUFFER_SIZE = 2048; 

    public static void main(String[] args) { 

    try { 
     File f = new File("DIR/inputs.zip"); 
     FileInputStream fis = new FileInputStream(f); 
     BufferedInputStream bis = new BufferedInputStream(fis); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     BufferedOutputStream bos = new BufferedOutputStream(baos); 
     byte[] buffer = new byte[BUFFER_SIZE]; 

     while (bis.read(buffer, 0, BUFFER_SIZE) != -1) { 
     bos.write(buffer); 
     } 

     bos.flush(); 
     bos.close(); 
     bis.close(); 

     Deque<Map<Integer, Object[]>> outputDataStack = ZipHandler1.unzip(baos); 

     //Output file 
     File fout = new File("DIR/inputs2.zip"); 

     ZipOutputStream zipOutput = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(fout))); 

     processZip(outputDataStack, zipOutput); 
     zipOutput.close(); 

    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

private static final void processZip(Deque<Map<Integer, Object[]>> outputDataStack, 
    ZipOutputStream zipOutput) throws IOException { 

while (!outputDataStack.isEmpty()) { 
    Map<Integer, Object[]> map = outputDataStack.pop(); 

    for (Map.Entry<Integer, Object[]> entry : map.entrySet()) { 
     System.out.println("KEY:" + entry.getKey()); 
     Object[] values = entry.getValue(); 
     String entryName = (String)values[0]; 

     if (entry.getKey().equals(ZipHandler1.FILE)) { 
      System.out.println(".........................."); 
      System.out.println("type: FILE"); 
      System.out.println("Name: " + entryName); 

      zipOutput.putNextEntry(new ZipEntry(entryName)); 
      byte[] outputByteArray = ((ByteArrayOutputStream)values[1]).toByteArray(); 

      IOUtils.write(outputByteArray, zipOutput); 
      zipOutput.closeEntry(); 
      ((ByteArrayOutputStream)values[1]).close(); 

     } else if (entry.getKey().equals(ZipHandler1.FOLDER)) { 
      System.out.println(".........................."); 
      System.out.println("type: FOLDER"); 
      System.out.println("Name: " + entryName); 

      zipOutput.putNextEntry(new ZipEntry(entryName)); 
      System.out.println(".........................."); 
      zipOutput.closeEntry(); 

     } else if (entry.getKey().equals(ZipHandler1.ZIP)) { 
      System.out.println(".........................."); 
      System.out.println("type: ZIP"); 
      System.out.println("Name: " + entryName); 

      zipOutput.putNextEntry(new ZipEntry(entryName)); 

      ByteArrayOutputStream innerZipByteArray = new ByteArrayOutputStream(BUFFER_SIZE); 
      ZipOutputStream innerZipOutput = new ZipOutputStream(
      new BufferedOutputStream(innerZipByteArray)); 

      processZip((Deque<Map<Integer,Object[]>>)values[1], innerZipOutput); 
      innerZipOutput.flush(); 
      IOUtils.write(zzzz.toByteArray(), zipOutput); 
      innerZipOutput.close(); 
      zipOutput.closeEntry(); 
      System.out.println(".........................."); 
     } 
      System.out.println(".........................."); 
      zipOutput.closeEntry(); 
     } 
    } 
} 
+0

누구?필요한 경우 추가 정보를 제공해 주어서 기쁩니다. –

+0

그래서 문제는 메모리에 zip 파일이 들어있는 zip 파일을 압축 해제하는 것입니다. –

답변

0

감사합니다!

대답은 나를 찾기가 꽤 어려웠고, 다른 사람들에게는 분명했을 것입니다.

짧은 대답 : 나는 너무 빨리

확인 INNER 우편 STREAM 닫기 WAS, 문제는 우편 바로 내에서 우편 번호를 저장한다? 내부 지퍼가 너무 빨리 폐쇄 되었기 때문에 글쎄, 나는 오류가 발생했다

솔루션 :

이 같은 내부 zip 파일 만들기 : 있는 ByteArrayOutputStream innerZipBufferOutput = 새로운있는 ByteArrayOutputStream (BUFFER_SIZE를); ZipOutputStream innerZipOutput = 새로운 ZipOutputStream ( 새로운 BufferedOutputStream (innerZipBufferOutput)); 내부 지퍼에

쓰기 바이트 (정보)

가까운 내부 지퍼 스트림 innerZipOutput.close(); **이 나는 바이트의 형태로이 시점의 데이터를

은 내부 zip 파일

ZipEntry newEntry = new ZipEntry(entryName); 
zipOutput.putNextEntry(newEntry); 

에 대한 외부 zip 파일에

설정 항목 에 innerZipBufferOutput입니다 * 잘못된 시간에 마감했다 외부 지퍼로 내부 지퍼 쓰기

zipOutput.write(innerZipBufferOutputByteArray); 

닫기 외부 지퍼

zipOutput.flush(); 
zipOutput.closeEntry(); 

Voila!

예 (코드 추출물) - 당신이 ZipOutputStream이 (외부 zip 파일)가

ByteArrayOutputStream innerZipBufferOutput = new ByteArrayOutputStream(BUFFER_SIZE); 
ZipOutputStream innerZipOutput = new ZipOutputStream(new BufferedOutputStream(innerZipBufferOutput)); 

<<process - e.g. create your inner zip file>> 

innerZipOutput.flush(); 
innerZipOutput.close(); 

ZipEntry newEntry = new ZipEntry(<<your entry name>>); 

zipOutput.setMethod(ZipOutputStream.STORED); 

byte[] innerZipBufferOutputByteArray = innerZipBufferOutput.toByteArray(); 

//Create the nested ZIP inside the outer ZIP 
ZipEntry newEntry = new ZipEntry(entryName); 
zipOutput.putNextEntry(newEntry); 

zipOutput.write(innerZipBufferOutputByteArray); 


zipOutput.closeEntry(); 
zipOutput.close();