[java] 파일을 압축 / 압축 해제하기에 적합한 Java 라이브러리는 무엇입니까? [닫은]

JDK 및 Apache 압축 라이브러리와 함께 제공되는 기본 Zip 라이브러리를 살펴본 결과 다음과 같은 3 가지 이유에 만족하지 않습니다.

  1. 부풀어 오르고 API 디자인이 잘못되었습니다. 내가해야 할 , 내 자신에 시내와 가까운 관련 스트림 캐치 예외 및 이동 바이트 버퍼 밖으로 입력, zip 파일을 보일러 플레이트 바이트 배열 출력의 50 개 라인을 쓰기 ? 이유는 간단한 API를 가질 수없는이 같은 외모 Zipper.unzip(InputStream zipFile, File targetDirectory, String password = null)Zipper.zip(File targetDirectory, String password = null)그 단지 작품?

  2. 압축을 풀면 파일 메타 데이터가 손상되고 암호 처리가 손상됩니다.

  3. 또한 내가 시도한 모든 라이브러리는 UNIX로 얻는 명령 줄 zip 도구에 비해 2-3 배 느 렸습니다.

나에게 (2)와 (3)은 사소한 점이지만 실제로 한 줄 인터페이스로 테스트를 거친 좋은 라이브러리를 원합니다.



답변

나는 그것을 늦게 알고 많은 답변이 있지만이 zip4j 는 내가 사용한 압축에 가장 적합한 라이브러리 중 하나입니다. 간단하고 (보일러 코드 없음) 암호로 보호 된 파일을 쉽게 처리 할 수 ​​있습니다.

import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.core.ZipFile;


public static void unzip(){
    String source = "some/compressed/file.zip";
    String destination = "some/destination/folder";
    String password = "password";

    try {
         ZipFile zipFile = new ZipFile(source);
         if (zipFile.isEncrypted()) {
            zipFile.setPassword(password);
         }
         zipFile.extractAll(destination);
    } catch (ZipException e) {
        e.printStackTrace();
    }
}

Maven 종속성은 다음과 같습니다.

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>1.3.2</version>
</dependency>


답변

함께 아파치 코 몬즈 – IO가IOUtils당신은이 작업을 수행 할 수 있습니다

try (java.util.zip.ZipFile zipFile = new ZipFile(file)) {
  Enumeration<? extends ZipEntry> entries = zipFile.entries();
  while (entries.hasMoreElements()) {
    ZipEntry entry = entries.nextElement();
    File entryDestination = new File(outputDir,  entry.getName());
    if (entry.isDirectory()) {
        entryDestination.mkdirs();
    } else {
        entryDestination.getParentFile().mkdirs();
        try (InputStream in = zipFile.getInputStream(entry);
             OutputStream out = new FileOutputStream(entryDestination)) {
            IOUtils.copy(in, out);
        }
    }
  }
}

여전히 상용구 코드이지만, 이국적이지 않은 의존성에는 Commons-IO 가 하나만 있습니다.


답변

JDK 만 사용하여 zip 파일 및 모든 하위 폴더를 추출하십시오.

private void extractFolder(String zipFile,String extractFolder)
{
    try
    {
        int BUFFER = 2048;
        File file = new File(zipFile);

        ZipFile zip = new ZipFile(file);
        String newPath = extractFolder;

        new File(newPath).mkdir();
        Enumeration zipFileEntries = zip.entries();

        // Process each entry
        while (zipFileEntries.hasMoreElements())
        {
            // grab a zip file entry
            ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
            String currentEntry = entry.getName();

            File destFile = new File(newPath, currentEntry);
            //destFile = new File(newPath, destFile.getName());
            File destinationParent = destFile.getParentFile();

            // create the parent directory structure if needed
            destinationParent.mkdirs();

            if (!entry.isDirectory())
            {
                BufferedInputStream is = new BufferedInputStream(zip
                .getInputStream(entry));
                int currentByte;
                // establish buffer for writing file
                byte data[] = new byte[BUFFER];

                // write the current file to disk
                FileOutputStream fos = new FileOutputStream(destFile);
                BufferedOutputStream dest = new BufferedOutputStream(fos,
                BUFFER);

                // read and write until last byte is encountered
                while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, currentByte);
                }
                dest.flush();
                dest.close();
                is.close();
            }


        }
    }
    catch (Exception e)
    {
        Log("ERROR: "+e.getMessage());
    }

}

Zip 파일 및 모든 하위 폴더 :

 private void addFolderToZip(File folder, ZipOutputStream zip, String baseName) throws IOException {
    File[] files = folder.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            addFolderToZip(file, zip, baseName);
        } else {
            String name = file.getAbsolutePath().substring(baseName.length());
            ZipEntry zipEntry = new ZipEntry(name);
            zip.putNextEntry(zipEntry);
            IOUtils.copy(new FileInputStream(file), zip);
            zip.closeEntry();
        }
    }
}


답변

체크 아웃 할 수있는 또 다른 옵션 은 Maven central의 https://github.com/zeroturnaround/zt-zip 에서 제공되는 zt-zip입니다.

표준 패킹 및 압축 풀기 기능 (스트림 및 파일 시스템) + 아카이브에서 파일을 테스트하거나 항목을 추가 / 제거하는 많은 도우미 메소드가 있습니다.


답변

zip4j를 사용 하여 폴더 / 파일을 압축 / 압축 해제하기위한 전체 구현


에서 항아리를 다운로드 여기추가 프로젝트 빌드 경로에. class울부 짖는 소리는 압축 또는 암호없이 파일이나 폴더를 추출 할 수 있습니다 보호 –

import java.io.File;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import net.lingala.zip4j.core.ZipFile;

public class Compressor {
    public static void zip(String targetPath, String destinationFilePath, String password) {
        try {
            ZipParameters parameters = new ZipParameters();
            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);

            if(password.length()>0){
                parameters.setEncryptFiles(true);
                parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
                parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
                parameters.setPassword(password);
            }

            ZipFile zipFile = new ZipFile(destinationFilePath);

            File targetFile = new File(targetPath);
            if(targetFile.isFile()){
                zipFile.addFile(targetFile, parameters);
            }else if(targetFile.isDirectory()){
                zipFile.addFolder(targetFile, parameters);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void unzip(String targetZipFilePath, String destinationFolderPath, String password) {
        try {
            ZipFile zipFile = new ZipFile(targetZipFilePath);
            if (zipFile.isEncrypted()) {
                zipFile.setPassword(password);
            }
            zipFile.extractAll(destinationFolderPath);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**/ /// for test only
    public static void main(String[] args) {

        String targetPath = "target\\file\\or\\folder\\path";
        String zipFilePath = "zip\\file\\Path";
        String unzippedFolderPath = "destination\\folder\\path";
        String password = "your_password"; // keep it EMPTY<""> for applying no password protection

        Compressor.zip(targetPath, zipFilePath, password);
        Compressor.unzip(zipFilePath, unzippedFolderPath, password);
    }/**/
}


답변

아주 좋은 프로젝트는 TrueZip 입니다.

TrueZIP는 가상 파일 시스템 (VFS) 용 Java 기반 플러그인 프레임 워크로 마치 일반 디렉토리 인 것처럼 아카이브 파일에 투명하게 액세스 할 수 있습니다.

예를 들어 ( 웹 사이트에서 ) :

File file = new TFile("archive.tar.gz/README.TXT");
OutputStream out = new TFileOutputStream(file);
try {
   // Write archive entry contents here.
   ...
} finally {
   out.close();
}


답변

다른 옵션은 JZlib 입니다. 내 경험상 zip4J보다 “파일 중심”이 적으므로 파일이 아닌 메모리 내 Blob에서 작업해야하는 경우 살펴볼 수 있습니다.