取消归档后文件权限未被保留 tar.gz
File permissions are not being preserved while after unarchive tar.gz
我正在尝试使用 Linux 和 Java 下的 Apache Compress 库取消归档 tar.gz 文件。
如何在取消存档时使用 Apache Compress 库保留文件权限 tar.gz?
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
中可用的方法(例如 setExecutable
、setReadable
和 setWritable
执行此操作。
详情请参考the official documentation
我正在尝试使用 Linux 和 Java 下的 Apache Compress 库取消归档 tar.gz 文件。
如何在取消存档时使用 Apache Compress 库保留文件权限 tar.gz?
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
中可用的方法(例如 setExecutable
、setReadable
和 setWritable
执行此操作。
详情请参考the official documentation