解压缩文件夹并选择一个特定的文件夹,然后再次将其压缩

时间:2020-04-02 16:57:23

标签: java

我有一个压缩文件夹(例如test.zip),当我将其解压缩时具有以下结构-

WebContent/config/somefiles
WebContent/css/somefile
Webcontent/fonts/somefiles
Webcontent/js/somefiles
WebContent/index.html

现在,我必须从此结构中删除WebContent。我的最终Unzip文件的根目录位置应为configcss,jsindex.html

请让我知道任何有效的JAVA代码,可以先将test.zip解压缩,然后绕过WebContent文件夹,然后再次压缩WebContent中存在的所有文件。

预先感谢!

2 个答案:

答案 0 :(得分:1)

这是一种常见的模式/活动,因此在您的工具包中应该是一个很好的模式/活动。

请参见下面的代码。有一种“选择”方法,供您根据需要自定义以驱动选择要传输或不传输的条目:

private static boolean select(String entryName) {
    return true; // Customize me
}

请注意,目录可能具有目录本身的条目(例如,“ meta-inf /”)以及目录中文件的条目(例如,“ meta-inf / manifest.mf”)。跳过目录条目不会跳过目录中的条目。

还请注意,这样可以避免将其解压缩到磁盘上。应避免这种情况,因为这会增加执行时间。 (但也请注意,整个条目不会加载到内存中;内存中只有一个缓冲区充满了数据。)

假设代码在“ transfer.jar”中,用法是:

用法:sample.transfer.TransferSample inputPath outputPath

例如,在自己的jar上运行该工具:

java -classpath transfer.jar sample.transfer.TransferSample transfer.jar transfer.jar.out

Transfer from [ transfer.jar ]
Transfer to [ transfer.jar.out ]
Transfer from [ c:\dev\transfer\transfer.jar ] (absolute path)
Transfer to [ c:\dev\transfer\transfer.jar.out ] (absolute path)
Entry [ META-INF/MANIFEST.MF ]: Selected
Transferred [ 25 ] bytes
Entry [ sample/ ]: Selected
Entry [ sample/transfer/ ]: Selected
Entry [ sample/transfer/TransferSample.class ]: Selected
Transferred [ 4061 ] bytes
Entry [ sample/transfer/TransferSample.java ]: Selected
Transferred [ 3320 ] bytes
Transfer Success

代码如下:

package sample.transfer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class TransferSample {

    public static void main(String args[]) {
        if ( args.length < 2 ) {
            System.out.println("Usage: " + TransferSample.class.getName() + " inputPath outputPath");
            return;
        }

        String inputPath = args[0];
        String outputPath = args[1];

        System.out.println("Transfer from [ " + inputPath + " ]");
        System.out.println("Transfer to [ " + outputPath + " ]");

        File inputFile = new File(inputPath);
        File outputFile = new File(outputPath);

        System.out.println("Transfer from [ " + inputFile.getAbsolutePath() + " ] (absolute path)");
        System.out.println("Transfer to [ " + outputFile.getAbsolutePath() + " ] (absolute path)");

        try ( InputStream inputStream = new FileInputStream(inputFile) ) { // throws IOException
            try ( OutputStream outputStream = new FileOutputStream(outputFile) ) { // throws IOException
                transfer(inputStream, outputStream);
                System.out.println("Transfer Success");
            }
        } catch ( IOException e ) {
            System.err.println("Transfer Failure");
            e.printStackTrace(System.err);
        }
    }

    // All static to keep the code simpler.

    public static void transfer(InputStream inputStream, OutputStream outputStream) throws IOException {
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        try {
            transfer(zipInputStream, zipOutputStream); // throws IOException
        } finally {
            zipOutputStream.finish(); // throws IOException
        }
    }

    private static final int BUFFER_SIZE = 64 * 1024;

    private static boolean select(String entryName) {
        return true; // Customize me
    }

    public static void transfer(ZipInputStream zipInputStream, ZipOutputStream zipOutputStream) throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE]; // Single buffer for all transfers

        ZipEntry inputEntry;
        while ( (inputEntry = zipInputStream.getNextEntry()) != null ) {
            String entryName = inputEntry.getName();

            if ( !select(entryName) ) {
                System.out.println("Entry [ " + entryName + " ]: Not selected");
                continue;
            } else {
                System.out.println("Entry [ " + entryName + " ]: Selected");
            }

            zipOutputStream.putNextEntry(inputEntry); // throws IOException

            if ( !inputEntry.isDirectory() ) {
                long bytesTransferred = transfer(zipInputStream, zipOutputStream, buffer); // throws IOException
                System.out.println("Transferred [ " + bytesTransferred + " ] bytes");

                zipOutputStream.closeEntry(); // throws IOException
            }
        }
    }

    private static long transfer(InputStream inputStream, OutputStream outputStream, byte[] buffer) throws IOException {
        long totalBytesRead = 0L;

        int bytesRead = 0;
        while ( (bytesRead = inputStream.read(buffer, 0, buffer.length)) != -1 ) { // throws IOEXception
            totalBytesRead += bytesRead;
            outputStream.write(buffer, 0, bytesRead);
        }

        return totalBytesRead;
    }
}

答案 1 :(得分:0)

我相信您会想要查看java.util.zip.ZipInputStream和java.util.zip.ZipOutputStream。这些方式的工作方式是,您需要遍历所有条目,然后从输入流式传输每个条目(当然不需要的条目除外),然后将其写入输出。

要注意的事情是:

  • 以足够小的块流式传输内容,即使您面对大量条目也不会耗尽内存(在您的情况下不必担心,但这是一个好习惯)
  • 确保正确打开和关闭条目
相关问题