2008-10-28 3 views
11

java.util.zip.*을 통해 zip 보관 파일을 만들면 결과 아카이브를 여러 볼륨으로 분할하는 방법이 있습니까?거대한 zip 파일을 여러 볼륨으로 분할하는 방법은 무엇입니까?

내 전체 보관 파일에 filesize (24 MB)이 있으며 파일 당 10MB 제한으로 3 개의 파일로 분할하고 싶습니다.
이 기능이있는 zip API가 있습니까? 또는 이것을 달성하는 다른 좋은 방법?

감사 Thollsten

답변

7

확인 : http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=38&t=004618

당신이 그렇게 도움이 될 것입니다 공개 API를 인식하지입니다. 사용 ZippedInput/OutputStream에 압축 된 크기를 가지고있는 동안 (당신이 프로그래밍 방식으로 그것을하지 않으려면, 그것을 할 것입니다 WinSplitter 같은 유틸리티가 있지만)

나는 모든 ZipEntry를은 그것을 시도하지만하지 않았습니다. 압축 파일을 만드는 동안 대략적인 크기를 예상 할 수 있습니다. 2MB의 압축 파일이 필요하면 항목의 누적 크기가 1.9MB가되고 Manifest 파일 및 다른 zip 파일 특정 요소에 0.1MB를 사용하면 파일에 쓰는 것을 중지 할 수 있습니다. 다음과 같이 그래서, 간단히 말해서, 당신은 ZippedInputStream에 대한 래퍼를 작성할 수 있습니다

import java.util.zip.ZipOutputStream; 
import java.util.zip.ZipEntry; 
import java.io.FileOutputStream; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.IOException; 

public class ChunkedZippedOutputStream { 

    private ZipOutputStream zipOutputStream; 

    private String path; 
    private String name; 

    private long currentSize; 
    private int currentChunkIndex; 
    private final long MAX_FILE_SIZE = 16000000; // Whatever size you want 
    private final String PART_POSTFIX = ".part."; 
    private final String FILE_EXTENSION = ".zip"; 

    public ChunkedZippedOutputStream(String path, String name) throws FileNotFoundException { 
     this.path = path; 
     this.name = name; 
     constructNewStream(); 
    } 

    public void addEntry(ZipEntry entry) throws IOException { 
     long entrySize = entry.getCompressedSize(); 
     if((currentSize + entrySize) > MAX_FILE_SIZE) { 
      closeStream(); 
      constructNewStream(); 
     } else { 
      currentSize += entrySize; 
      zipOutputStream.putNextEntry(entry); 
     } 
    } 

    private void closeStream() throws IOException { 
     zipOutputStream.close(); 
    } 

    private void constructNewStream() throws FileNotFoundException { 
     zipOutputStream = new ZipOutputStream(new FileOutputStream(new File(path, constructCurrentPartName()))); 
     currentChunkIndex++; 
     currentSize = 0; 
    } 

    private String constructCurrentPartName() { 
     // This will give names is the form of <file_name>.part.0.zip, <file_name>.part.1.zip, etc. 
     StringBuilder partNameBuilder = new StringBuilder(name); 
     partNameBuilder.append(PART_POSTFIX); 
     partNameBuilder.append(currentChunkIndex); 
     partNameBuilder.append(FILE_EXTENSION); 
     return partNameBuilder.toString(); 
    } 
} 

위의 프로그램은 단지 접근 방법의 힌트가 아닌 수단에 의해 최종 솔루션입니다.

+1

이것은 몇 개의 개별 zip 파일입니다. 맞습니까? 하나의 다중 볼륨 zip 파일이 아닙니다. – mcv

+0

이 코드는이 질문에 대한 답변으로 작동합니다. - http://stackoverflow.com/questions/11104889/how-to-create-java-zip-archives-with-a-max-file-size-limit –

5

출력이 pkzip 및 winzip과 호환되도록하려면이 작업을 수행하는 모든 오픈 소스 라이브러리를 알지 못합니다. 우리 애플 리케이션 중 하나에 대해 비슷한 요구 사항이 있었고, 필자는 자체 구현 (zip 표준과 호환 가능)을 작성했습니다. 기억해 보면 가장 어려운 점은 개별 파일을 즉석에서 생성해야한다는 것입니다 (대부분의 zip 유틸리티가 작동하는 방식은 큰 zip 파일을 만든 다음 나중에 되돌려 분할하는 것입니다). 쓰기 위해 하루가 소요되었고 디버깅을하기 위해 2 일 걸렸습니다.

우편 번호는 파일 형식이 어떻게되어 있는지를 설명합니다. 슬리브를 조금 두껍게 두려워하지 않으면이 작업을 확실히 수행 할 수 있습니다. 직접 압축 파일 생성기를 구현해야하지만 Java Deflator 클래스를 사용하여 압축 된 데이터의 세그먼트 스트림을 생성 할 수 있습니다. 파일 및 섹션 헤더를 직접 생성해야하지만 바이트 일뿐입니다. 너무 어렵지 않습니다. 잠수함에 들어가면

여기에 zip specification 섹션이 있습니다. K는 특별히 찾고있는 정보가 있지만 A, B, C 및 F도 읽어야합니다. 정말로 큰 파일 (우리는)을 다루는 경우 Zip64에 들어가야 할 것입니다. 그러나 24MB의 경우에는 괜찮습니다.

다이빙을하고 시도해 보려면 질문에 답하는 경우 다시 게시하고 포인터를 제공 할 수 있는지 확인해보십시오.

+0

다중 볼륨 zip 파일에 문제가 있습니다. 특히 단일 파일 구성 요소가 디스크 파일 이상으로 분할되는 경우 file.zx01에는 파일 헤더와 압축 된 데이터의 첫 번째 부분이 있고 file.zx02에는 나머지 압축 된 데이터가 있습니다.하지만 어떤 이유로 파일을 재구성 할 수 없으며 그 이유를 모르겠습니다. 여기에 어떤 경험이 있습니까? – vy32

관련 문제