문제

폴더 구조가 포함 된 zip 파일이 있습니다.

  • 메인 폴더/
    • subfolder1/
    • subfolder2/
    • 하위 폴더 3/
      • 파일 3.1
      • 파일 3.2

폴더 이름을 바꾸고 싶습니다 main-folder 말하면 versionXY Java를 사용한 바로 Zip 파일 내부.

전체 zip 파일을 추출하고 새 폴더 이름을 사용하여 새 파일을 재현하는 것보다 간단한 방법이 있습니까?

도움이 되었습니까?

해결책

Zip은 아카이브 형식이므로 돌연변이에는 일반적으로 파일을 다시 작성하는 것이 포함됩니다.

Zip의 특정 기능도 방해가됩니다 (Zip은 "기능"으로 가득합니다). 아카이브 끝의 중앙 디렉토리뿐만 아니라 각 구성 요소 파일에는 파일 이름이 선행됩니다. Zip은 디렉토리의 개념이 없습니다. 파일 이름은 "/"문자 (및 "../"와 같은 하위 문자를 포함하는 문자열 일뿐입니다.

따라서 실제로 사용 파일을 복사해야합니다. ZipInputStream 그리고 ZipOutputStream, 당신이 갈 때 이름을 바꿉니다. 당신이 정말로 원한다면 당신이 자신의 버퍼링을 수행하는 파일을 다시 작성할 수 있습니다. 표준 API가 압축 형태로 데이터를 얻을 수있는 수단이 없기 때문에 프로세스는 내용물을 다시 압축합니다.

다른 팁

나는 당신이 Java에 대해 물었다는 것을 알고 있지만 보관 목적을 위해 .NET에 대한 메모를 제공 할 것이라고 생각했습니다.

dotnetzip 항목의 이름을 바꿀 수있는 ZIP 파일 용 .NET 라이브러리입니다. Tom Hawtin의 답장에 따르면 디렉토리는 ZIP 파일 메타 데이터의 일류 엔티티가 아니며 결과적으로 "이름 변경 디렉토리"동사를 노출시키는 ZIP 라이브러리는 없습니다. 그러나 일부 라이브러리를 사용하면 특정 디렉토리를 나타내는 이름이있는 모든 항목의 이름을 바꿀 수 있으므로 원하는 결과를 제공합니다.

dotnetzip에서는 다음과 같습니다.

 var regex = new Regex("/OldDirName/.*$");
 int renameCount= 0;
 using (ZipFile zip = ZipFile.Read(ExistingZipFile))
 {
    foreach (ZipEntry e in zip)
    {
        if (regex.IsMatch(e.FileName))
        {
            // rename here
            e.FileName = e.FileName.Replace("/OldDirName/", "/NewDirName/");
            renameCount++;
        }
    }
    if (renameCount > 0)
    {
        zip.Comment = String.Format("This archive has been modified. {0} entries have been renamed.", renameCount);
        // any changes to the entries are made permanent by Save()
        zip.Save();  // could also save to a new zip file here
    }
 }

사용 조항 내부에서 항목을 추가하거나 제거 할 수도 있습니다.

동일한 파일에 저장되면 DotNetZip은 변경된 메타 데이터 (항목 헤더 및 이름이 바뀌는 항목에 대한 중앙 디렉토리 레코드 만 다시 작성하여 대형 아카이브로 시간을 절약합니다. 새 파일이나 스트림에 저장하면 모든 ZIP 데이터가 작성됩니다.

이것은 속임수를하고 있습니다. 파일이 아닌 중앙 디렉토리에서만 작동하기 때문에 빠르게 타 오릅니다.

//  rezip( zipfile, "/main-folder", "/versionXY" );

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;


protected void rezip( String zipfile, String olddir, String newdir ) {

    Path zipFilePath = Paths.get( zipfile );
    try (FileSystem fs = FileSystems.newFileSystem( zipFilePath, null )) {
        Path oldpathInsideZipPath = fs.getPath( olddir );
        if( ! Files.exists( Paths.get( newdir ) ) )
            Files.createDirectory( Paths.get( newdir ) );

        if ( Files.exists( oldpathInsideZipPath, LinkOption.NOFOLLOW_LINKS ) ) {
            Files.walkFileTree(oldpathInsideZipPath, new SimpleFileVisitor<Path>() {
                 @Override
                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                     throws IOException
                 {
                     if( file.toString().indexOf( olddir ) > -1 ){
                         String a = file.toString().replaceAll( olddir, newdir );
                         Path b = fs.getPath( a );
                         if( ! Files.exists( b.getParent() ) ){
                             Files.createDirectories( b.getParent() );
                         }
                         Files.move( file, b, LinkOption.NOFOLLOW_LINKS );
                     }
                     return FileVisitResult.CONTINUE;
                 }
                 @Override
                 public FileVisitResult postVisitDirectory(Path dir, IOException e)
                     throws IOException
                 {
                     if (e == null) {
                         Files.delete(dir);
                         return FileVisitResult.CONTINUE;
                     } else {
                         // directory iteration failed
                         throw e;
                     }
                 }
             });
        }
        fs.close();
    } catch ( Exception e ) {
        e.printStackTrace();
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top