如何以最小的工作空间压缩此文件夹,以便用Java解压
我有一个文件夹,其中包含在linux上创建的文件,我目前使用gzip(即tar.gz)对这些文件进行tar和压缩 然后在稍后的阶段,该文件被复制到另一台linux机器上的一个文件系统中,并使用Java提取到另一个文件系统中 我的问题是存档是3GB压缩,5GB未压缩。这两个文件系统分别是4GB和6GB。我将压缩的归档文件复制到4GB fs,但当我尝试将其解压缩到6GB时,它会在解压缩时复制到6GB fs,因此6GB需要足够的空间来容纳压缩和未压缩的格式 我不清楚为什么要创建这个临时文件,如果我这么做的话如何以最小的工作空间压缩此文件夹,以便用Java解压,java,compression,gzip,tar,Java,Compression,Gzip,Tar,我有一个文件夹,其中包含在linux上创建的文件,我目前使用gzip(即tar.gz)对这些文件进行tar和压缩 然后在稍后的阶段,该文件被复制到另一台linux机器上的一个文件系统中,并使用Java提取到另一个文件系统中 我的问题是存档是3GB压缩,5GB未压缩。这两个文件系统分别是4GB和6GB。我将压缩的归档文件复制到4GB fs,但当我尝试将其解压缩到6GB时,它会在解压缩时复制到6GB fs,因此6GB需要足够的空间来容纳压缩和未压缩的格式 我不清楚为什么要创建这个临时文件,如果我这么
cd destination folder
tar -zxvf source file
它可以在不耗尽空间的情况下工作,但我需要使用纯Java而不是命令行来解压缩它
有没有更好的方法来压缩文件夹,因为只要可以用Java代码解压,Im就不受任何特定格式的限制。我无法修改/重新配置这两个文件系统的大小-它需要在这些边界内工作。你让我对这一个感到好奇,是的,这并不难。我使用TCP服务器和客户机只是为了完全分离输入/输出流,以确保没有欺诈行为 实际上,在服务器上读取原始ZIP数据并将其发送到客户端。然后,客户端将该数据解释为
ZipInputStream
,并将所有条目写入输出文件夹。事实证明,您甚至不需要发送大块数据,只需要真正分配缓冲区。我分析了它发送超过200mb的zip文件时的内存消耗情况
最后,您确实得到了一个不错的SocketException
,但这是意料之中的,因为除了必需的错误处理之外,我几乎没有添加任何错误处理。客户端关闭连接,而服务器不喜欢这样,因此它会抛出一个错误,但所有数据都已完成,所以谁在乎呢
我为ZIP文件编写了这段代码,因为我没有注意到,但我想我会在anway上发布。您可以在线使用一些库对其进行调整,以使用TAR输入流,但是代码应该给出一般的Jist
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Object serverWait = new Object();
startServer(serverWait);
synchronized (serverWait) {
// make sure our server is started and accepting clients, otherwise we run the risk of starting the client before the server is started
serverWait.wait(2000);
}
startClient();
}
private static void startServer(final Object serverWait) {
new Thread(new Runnable() {
@Override
public void run() {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
try {
serverSocket = new ServerSocket(5555);
synchronized (serverWait) {
serverWait.notify();
}
socket = serverSocket.accept();
System.out.println("Client accepted, sending data");
// just send over the raw zip file and let the client sort through how to parse it
is = new FileInputStream("f:\\so\\zip_transfer\\ZipFile.zip");
int numRead = 0;
byte [] buffer = new byte[2048];
while((numRead = is.read(buffer)) != -1) {
socket.getOutputStream().write(buffer, 0, numRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
safeClose(socket);
safeClose(serverSocket);
safeClose(is);
}
}
}).start();
}
private static void startClient() {
new Thread(new Runnable() {
@Override
public void run() {
Socket socket = null;
ZipInputStream is = null;
try {
socket = new Socket("127.0.0.1", 5555);
System.out.println("Client connected, retrieving data");
// the data we are receiving is in zip format
is = new ZipInputStream(socket.getInputStream());
extactZipInputStream(is, new File("f:\\so\\zip_transfer\\OutputDirectory"));
} catch (IOException e) {
e.printStackTrace();
} finally {
safeClose(socket);
safeClose(is);
}
}
}).start();
}
public static void extactZipInputStream(ZipInputStream is, File outputFolder) throws ZipException, IOException {
ZipEntry entry = null;
// Just keep going until we dont have any entries left.
while((entry = is.getNextEntry()) != null) {
System.out.println("Entry: " + entry.getName());
File file = new File(outputFolder, entry.getName());
if(entry.isDirectory()) {
// make all the path a direcotyr
file.mkdirs();
} else {
// last one isnt a directory its our file, only make our parents
file.getParentFile().mkdirs();
// write the file to the system
FileOutputStream fos = new FileOutputStream(file);
int numRead = 0;
byte [] buffer = new byte[2048];
while((numRead = is.read(buffer)) != -1) {
fos.write(buffer, 0, numRead);
}
fos.close();
}
is.closeEntry();
}
}
private static void safeClose(Closeable closable) {
try {
if(closable != null) {
closable.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
仅供参考:刚刚意识到,在tar.gz文件中,文件是tar文件,然后tar文件是gzip文件,所以在解压缩到tar的中间步骤时很难避免。但是,如果我手动gzip每个文件,然后tar如下所示:
cd foldertozip
gzip *
cd ..
tar -cvf foldertozip.tar folderzip
tar的大小与原始的foldertozip.tar.gz完全相同,但不需要临时步骤
然后我可以:
- 将foldertozip.tar复制到4GB fs
- 将foldertozip.tar解压缩到6GB fs
- 对于foldertozip中的每个文件 解压缩每个.gz
我已经对此进行了测试,它对我有效。在传输数据时开始解压缩它?我说发送300mb的压缩数据块,然后一次解压缩一个,在这两种情况下,您都可以保持在1gb的利润范围内side@ug_请提供更多详细信息,我如何将文件分割成可以独立解压缩的块?感谢您的努力,但不幸的是,您的回答没有抓住关键点,即文件被涂上焦油,然后被gzip压缩,因此必须先被gzip压缩成普通焦油,然后才能恢复。我现在有一个解决方案,我将在一分钟后发布