JavaでZipファイル内のファイル/フォルダの名前を変更しますか?
質問
次のようなフォルダー構造を含む zip ファイルがあります
- メインフォルダ/
- サブフォルダー1/
- サブフォルダー2/
- サブフォルダー3/
- ファイル3.1
- ファイル3.2
フォルダの名前を変更したいのですが main-folder
言ってみましょう versionXY
その zip ファイル内で Java を使用しています。
zip ファイル全体を抽出し、新しいフォルダー名を使用して新しいファイルを再作成するよりも簡単な方法はありますか?
解決
Zipはアーカイブ形式ですので、一般的に変異すると、ファイルの書き換えを必要とする。
郵便番号の一部の特定の機能も邪魔に(ジップは、「機能」がいっぱいです)。同様に、アーカイブの終わりに中央ディレクトリとして、各コンポーネントファイルは、そのファイル名が先行します。 Zipは、ディレクトリの概念がありません - ファイル名は、」../".
のように「/」文字(およびサブストリングを含めることが起こるだけの文字列ですだから、あなたは本当にあなたが行くように名前の変更、ZipInputStream
とZipOutputStream
を使用してファイルをコピーする必要があります。あなたは本当にあなたに望んでいた場合は、独自のバッファリングを行っている場所にファイルを書き換えることができます。標準APIが圧縮形式でデータを取得する手段を持たないように、プロセスは内容が再圧縮させることがない。
他のヒント
私が知っているあなたは、Javaについて尋ねたが、単にアーカイブの目的のために私は、.NETに関するメモを貢献するだろうと思いました。
DotNetZip のエントリの名前の変更を可能にzipファイルの.NETライブラリです。トムホーティンの応答状態として、ディレクトリはない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データのすべてが書き込まれます。
私は、あなたがコモンズ圧縮を使用してこのタスクのヘルプを見つけることができると思います特に ZipArchiveEntryする
これはトリックをやっています。それは中央のディレクトリではなくファイルでのみ動作しますので、高速で燃えるます。
// 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();
}
}