apache commons 压缩的 Tar 问题

发布于 2024-08-17 11:58:11 字数 1220 浏览 3 评论 0原文

我很难尝试使用压缩库来压缩某些文件。

我的代码如下,取自 commons.compress wiki 示例:

    private static File createTarFile(String[] filePaths, String saveAs) throws Exception{

    File tarFile = new File(saveAs);
    OutputStream out = new FileOutputStream(tarFile);

    TarArchiveOutputStream aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("tar", out);

    for(String filePath : filePaths){
        File file = new File(filePath);
        TarArchiveEntry entry = new TarArchiveEntry(file);
        entry.setSize(file.length());
        aos.putArchiveEntry(entry);
        IOUtils.copy(new FileInputStream(file), aos);
        aos.closeArchiveEntry();
    }
    aos.finish();
    out.close();


    return tarFile;
}

过程中没有错误,但是当我尝试解压文件时,我得到以下信息:

XXXX:XXXX /home/XXXX$ tar -xf typeCommandes.tar
tar: Unexpected EOF in archive
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now

另外,存档的大小比原始文件,这对于 tar 来说是不正常的,所以确实有问题......

-rw-r--r--  1 XXXX nobody 12902400 Jan 14 17:11 typeCommandes.tar
-rw-r--r--  1 XXXX nobody 12901888 Jan 14 17:16 typeCommandes.csv

任何人都可以告诉我我做错了什么?谢谢

I'm having a hard time trying to tar some files using the compress library.

My code is the following, and is taken from the commons.compress wiki exemples :

    private static File createTarFile(String[] filePaths, String saveAs) throws Exception{

    File tarFile = new File(saveAs);
    OutputStream out = new FileOutputStream(tarFile);

    TarArchiveOutputStream aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("tar", out);

    for(String filePath : filePaths){
        File file = new File(filePath);
        TarArchiveEntry entry = new TarArchiveEntry(file);
        entry.setSize(file.length());
        aos.putArchiveEntry(entry);
        IOUtils.copy(new FileInputStream(file), aos);
        aos.closeArchiveEntry();
    }
    aos.finish();
    out.close();


    return tarFile;
}

There is no error during the process, but when I try to untar the file, I got the following :

XXXX:XXXX /home/XXXX$ tar -xf typeCommandes.tar
tar: Unexpected EOF in archive
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now

Also, the archive IS slighty smaller in size than the original file, which isnt normal for a tar, so there DO is a problem...

-rw-r--r--  1 XXXX nobody 12902400 Jan 14 17:11 typeCommandes.tar
-rw-r--r--  1 XXXX nobody 12901888 Jan 14 17:16 typeCommandes.csv

Anyone can tell me what I'm doing wrong ? Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

薄凉少年不暖心 2024-08-24 11:58:11

您没有关闭 TarArchiveOutputStream。在 aos.finish() 之后添加 aos.close()

You're not closing the TarArchiveOutputStream. Add aos.close() after aos.finish()

土豪我们做朋友吧 2024-08-24 11:58:11

对上面的代码进行小修正。
它不会关闭输入流,而 Apache lib 假定流是通过调用 client 来管理的。
请参阅下面的修复(将此代码放在“aos.putArchiveEntry(entry)”行之后):

FileInputStream fis = new FileInputStream(fileForPuttingIntoTar);
IOUtils.copy(fis, aos);
fis.close();
aos.closeArchiveEntry();

Small correction to the code above.
It does not close input stream, while Apache lib assumes that stream is managed by calling client.
See the fix below (put this code after the line 'aos.putArchiveEntry(entry)') :

FileInputStream fis = new FileInputStream(fileForPuttingIntoTar);
IOUtils.copy(fis, aos);
fis.close();
aos.closeArchiveEntry();
十雾 2024-08-24 11:58:11

这里的例子-> http://commons.apache.org/compress/examples.html 使用该方法putNextEntry(entry) 你似乎省略了。

the example here -> http://commons.apache.org/compress/examples.html uses the method putNextEntry(entry) which you seem to omit.

戈亓 2024-08-24 11:58:11

另请参阅我的答案此处

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;

public class TarUpdater {

        private static final int buffersize = 8048;

        public static void updateFile(File tarFile, File[] flist) throws IOException {
            // get a temp file
            File tempFile = File.createTempFile(tarFile.getName(), null);
            // delete it, otherwise you cannot rename your existing tar to it.
            if (tempFile.exists()) {
                tempFile.delete();
            }

            if (!tarFile.exists()) {
                tarFile.createNewFile();
            }

            boolean renameOk = tarFile.renameTo(tempFile);
            if (!renameOk) {
                throw new RuntimeException(
                        "could not rename the file " + tarFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath());
            }
            byte[] buf = new byte[buffersize];

            TarArchiveInputStream tin = new TarArchiveInputStream(new FileInputStream(tempFile));

            OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(tarFile.toPath()));
            TarArchiveOutputStream tos = new TarArchiveOutputStream(outputStream);
            tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);

            //read  from previous  version of  tar  file
            ArchiveEntry entry = tin.getNextEntry();
            while (entry != null) {//previous  file  have entries
                String name = entry.getName();
                boolean notInFiles = true;
                for (File f : flist) {
                    if (f.getName().equals(name)) {
                        notInFiles = false;
                        break;
                    }
                }
                if (notInFiles) {
                    // Add TAR entry to output stream.
                    if (!entry.isDirectory()) {
                        tos.putArchiveEntry(new TarArchiveEntry(name));
                        // Transfer bytes from the TAR file to the output file
                        int len;
                        while ((len = tin.read(buf)) > 0) {
                            tos.write(buf, 0, len);
                        }
                    }
                }
                entry = tin.getNextEntry();
            }
            // Close the streams
            tin.close();//finished  reading existing entries 
            // Compress new files

            for (int i = 0; i < flist.length; i++) {
                if (flist[i].isDirectory()) {
                    continue;
                }
                InputStream fis = new FileInputStream(flist[i]);
                TarArchiveEntry te = new TarArchiveEntry(flist[i],flist[i].getName());
                //te.setSize(flist[i].length());
                tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
                tos.setBigNumberMode(2);
                tos.putArchiveEntry(te); // Add TAR entry to output stream.

                // Transfer bytes from the file to the TAR file
                int count = 0;
                while ((count = fis.read(buf, 0, buffersize)) != -1) {
                    tos.write(buf, 0, count);
                }
                tos.closeArchiveEntry();
                fis.close();
            }
            // Complete the TAR file
            tos.close();
            tempFile.delete();
        }
    }

See also my answer here

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;

public class TarUpdater {

        private static final int buffersize = 8048;

        public static void updateFile(File tarFile, File[] flist) throws IOException {
            // get a temp file
            File tempFile = File.createTempFile(tarFile.getName(), null);
            // delete it, otherwise you cannot rename your existing tar to it.
            if (tempFile.exists()) {
                tempFile.delete();
            }

            if (!tarFile.exists()) {
                tarFile.createNewFile();
            }

            boolean renameOk = tarFile.renameTo(tempFile);
            if (!renameOk) {
                throw new RuntimeException(
                        "could not rename the file " + tarFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath());
            }
            byte[] buf = new byte[buffersize];

            TarArchiveInputStream tin = new TarArchiveInputStream(new FileInputStream(tempFile));

            OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(tarFile.toPath()));
            TarArchiveOutputStream tos = new TarArchiveOutputStream(outputStream);
            tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);

            //read  from previous  version of  tar  file
            ArchiveEntry entry = tin.getNextEntry();
            while (entry != null) {//previous  file  have entries
                String name = entry.getName();
                boolean notInFiles = true;
                for (File f : flist) {
                    if (f.getName().equals(name)) {
                        notInFiles = false;
                        break;
                    }
                }
                if (notInFiles) {
                    // Add TAR entry to output stream.
                    if (!entry.isDirectory()) {
                        tos.putArchiveEntry(new TarArchiveEntry(name));
                        // Transfer bytes from the TAR file to the output file
                        int len;
                        while ((len = tin.read(buf)) > 0) {
                            tos.write(buf, 0, len);
                        }
                    }
                }
                entry = tin.getNextEntry();
            }
            // Close the streams
            tin.close();//finished  reading existing entries 
            // Compress new files

            for (int i = 0; i < flist.length; i++) {
                if (flist[i].isDirectory()) {
                    continue;
                }
                InputStream fis = new FileInputStream(flist[i]);
                TarArchiveEntry te = new TarArchiveEntry(flist[i],flist[i].getName());
                //te.setSize(flist[i].length());
                tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
                tos.setBigNumberMode(2);
                tos.putArchiveEntry(te); // Add TAR entry to output stream.

                // Transfer bytes from the file to the TAR file
                int count = 0;
                while ((count = fis.read(buf, 0, buffersize)) != -1) {
                    tos.write(buf, 0, count);
                }
                tos.closeArchiveEntry();
                fis.close();
            }
            // Complete the TAR file
            tos.close();
            tempFile.delete();
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文