java - 解压 tar.gz 后,文件权限不会被保留

标签 java apache-commons

我正在尝试在 Linux 下使用 Java 来使用 Apache 压缩库解压缩 tar.gz 文件。

解压 tar.gz 时如何使用 Apache 压缩库保留文件权限?

public void run(ByteTransferCallback callback) throws IOException
{
    this.entries = new HashSet<>();


    try (TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(
            new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(this.tarGZipFile)))))
    {
        TarArchiveEntry entry = null;

        while ((entry = tarArchiveInputStream.getNextTarEntry()) != null)
        {
            if (entry.getName().startsWith(this.tarGZipPath))
            {
                boolean cancelled = !unarchiveEntry(tarArchiveInputStream, entry, callback);
                if (cancelled) break;
            }
        }

    }

}


protected boolean unarchiveEntry(TarArchiveInputStream tar, TarArchiveEntry 
     entry, ByteTransferCallback callback) throws IOException
{
    File entryDestination = new File(this.destination, 
    entry.getName().replaceFirst(this.tarGZipPath, ""));

    entryDestination.getParentFile().mkdirs();

    this.entries.add(entryDestination);

    boolean result = false;

    if (entry.isDirectory())
    {
        entryDestination.mkdirs();
        result = true;
    }
    else
    {
        result = unarchiveFileEntry(tar, entry, entryDestination, callback);
    }

    return result;
}



protected boolean unarchiveFileEntry(TarArchiveInputStream tar, 
TarArchiveEntry entry, File destination, ByteTransferCallback callback) 
throws IOException
{
        try(OutputStream out = new FileOutputStream(destination))
        {
            return copy(tar, out, callback);
        }
}


protected boolean copy(InputStream in, OutputStream out, 
ByteTransferCallback callback) throws IOException
{
    int numBytes = 0;
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];

    boolean cancelled = false;

    while (EOF != (numBytes = in.read(buffer)) && !cancelled)
    {
        out.write(buffer, 0, numBytes);
        cancelled = !callback.onBytesTransferred(numBytes);
    }

    return !cancelled;
}

从每个条目中,我可以使用 TarArchiveEntry.getMode() 获得 Unix 格式的权限,但如何将其设置为每个未归档的文件?

最佳答案

在 Linux/Unix 下,普通用户无法将文件系统对象的所有权转移给另一个用户。只有 root (UID 0) 可以。 在这种情况下,您的程序需要以 root 身份运行,并且需要使用系统调用 chown() 及相关内容(请参阅 man 2 chown )。

对于文件权限以及时间和日期,您需要使用系统调用 utime() 及相关调用(请参阅 man 2 utime)。

您可以通过 Java 使用 java.io.File 中提供的方法(例如 setExecutablesetReadablesetWritable)来执行此操作。 请引用the official documentation了解详情。

关于java - 解压 tar.gz 后,文件权限不会被保留,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50406448/

相关文章:

java - 属性文件未反射(reflect)使用 Apache Commons Configuration 修改的更改

java - 使用仅字符串格式化程序将纪元时间戳字符串转换为Joda日期时间

java - 打开带有建议日期的 DatePicker

java - 如何在 Java 中将字节大小转换为人类可读的格式?

java - 无法在 Apache Commons Mail 上将套接字转换为 TLS

java - 为什么我使用 Apache Commons FileUpload 得到 "FileUploadException: Stream ended unexpectedly"?

java - Android - 无法实例化 Activity - 应用已停止

java - 创建异常类时,是否应该实现 java.lang.Exception 的所有构造函数?

java - 在 netbeans 中的 JTable 中填充数据

java - 如何将文件从 Java servlet 上传到 Tomcat/webapps 中 Web 服务器上的某个位置