我有一个文件夹,其中包含在linux上创建的文件,我目前使用gzip进行tar压缩(即tar.gz)
然后在稍后阶段将文件复制到另一台Linux机器到一个文件系统,然后使用Java将其解压缩到另一个文件系统。
我的问题是存档是3GB压缩,5GB未压缩。两个文件系统是4GB和6GB我将压缩存档复制到4GB fs但是当我尝试将其解压缩到6GB时,它被复制到6GB fs,因为它是未压缩的,因此6GB需要足够的空间用于压缩和未压缩的格式,但它没有。
我不清楚为什么要创建这个临时文件,如果我这样做
cd destination folder
tar -zxvf source file
它可以在没有空间不足的情况下工作,但我需要使用纯Java而不是命令行解压缩它
是否有更好的方法来压缩文件夹,因为我不受任何特定格式的限制,只要它可以用Java代码解压缩即可。我无法修改/重新配置两个文件系统的大小 - 它需要在这些边界内工作。
答案 0 :(得分:1)
仅供参考:刚刚意识到在tar.gz文件中文件被涂焦,然后tar文件被gzip压缩,因此当解压缩到tar的临时步骤时很难避免。但是,如果我手动gzip每个文件然后tar ,如下所示:
cd foldertozip
gzip *
cd ..
tar -cvf foldertozip.tar folderzip
foldertozip.tar的大小与原始的foldertozip.tar.gz完全相同,但不需要临时步骤。
然后我可以:
因此我们在6GB fs上使用的唯一额外临时空间是解压缩每个gz文件所需的空间。
我已经对此进行了测试,它对我有用。
答案 1 :(得分:0)
你让我对这个感到好奇,而且这并不困难。我使用TCP服务器和客户端只是为了完全分离输入/输出流,以确保没有恶作剧。
基本上读取服务器上的原始ZIP数据并将其发送到客户端。然后,客户端将该数据解释为ZipInputStream
,并将所有条目写入输出文件夹。事实证明,你甚至不需要发送大块数据,只有缓冲区才真正分配。我发现它发送了一个200mb的zip文件,内存消耗几乎没有开始。
你最后得到了一个不错的SocketException
,但这是预期的,因为我几乎没有添加任何错误处理而不是必需的。客户端关闭连接,服务器不喜欢这样,所以它会抛出一个错误,但所有数据都已完成,所以谁在乎呢!
我为ZIP文件编写了这段代码,因为我没有注意,但我想我会先发帖子。您可以使用某些库在线调整它以使用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();
}
}