Trong khi cố gắng nén lưu trữ bằng cách sử dụng java.util.zip
Tôi gặp phải rất nhiều sự cố mà hầu hết tôi đã giải quyết. Bây giờ tôi cuối cùng đã nhận được một số đầu ra tôi đấu tranh với việc sản xuất "đúng". Tôi có một tệp ODT được trích xuất (thư mục sẽ phù hợp hơn với mô tả) mà tôi đã thực hiện một số sửa đổi. Bây giờ tôi muốn nén thư mục đó để tạo lại cấu trúc tệp ODT. Nén thư mục và đổi tên thư mục để kết thúc bằng .odt hoạt động tốt nên không có vấn đề gì.java.util.zip - Tái cấu trúc thư mục
Vấn đề chính là tôi mất cấu trúc bên trong của thư mục. Mọi thứ trở nên "phẳng" và tôi dường như không tìm được cách để bảo tồn cấu trúc nhiều lớp ban đầu. Tôi sẽ đánh giá cao một số trợ giúp về điều này vì tôi dường như không thể tìm thấy vấn đề.
Dưới đây là các đoạn mã liên quan:
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
FILEPATH.substring(0, FILEPATH.lastIndexOf(SEPARATOR) + 1).concat("test.zip")));
compressDirectory(TEMPARCH, out);
Các SEPARATOR
là file hệ thống tách và FILEPATH
là filepath của ODT gốc mà tôi sẽ ghi đè lên nhưng chưa thực hiện ở đây cho mục đích thử nghiệm. Tôi chỉ cần viết vào một tệp test.zip trong cùng một thư mục.
private void compressDirectory(String directory, ZipOutputStream out) throws IOException
{
File fileToCompress = new File(directory);
// list contents.
String[] contents = fileToCompress.list();
// iterate through directory and compress files.
for(int i = 0; i < contents.length; i++)
{
File f = new File(directory, contents[i]);
// testing type. directories and files have to be treated separately.
if(f.isDirectory())
{
// add empty directory
out.putNextEntry(new ZipEntry(f.getName() + SEPARATOR));
// initiate recursive call
compressDirectory(f.getPath(), out);
// continue the iteration
continue;
}else{
// prepare stream to read file.
FileInputStream in = new FileInputStream(f);
// create ZipEntry and add to outputting stream.
out.putNextEntry(new ZipEntry(f.getName()));
// write the data.
int len;
while((len = in.read(data)) > 0)
{
out.write(data, 0, len);
}
out.flush();
out.closeEntry();
in.close();
}
}
}
Thư mục chứa tệp cần nén ở đâu đó trong không gian người dùng và không nằm trong cùng thư mục với tệp kết quả. Tôi cho rằng điều này có thể gây rắc rối nhưng tôi không thể thực sự thấy như thế nào. Ngoài ra tôi thấy rằng vấn đề có thể được sử dụng trong cùng một dòng để xuất nhưng một lần nữa tôi không thể nhìn thấy như thế nào. Tôi đã thấy trong một số ví dụ và hướng dẫn mà họ sử dụng getPath()
thay vì getName()
nhưng thay đổi cung cấp cho tôi một tệp zip trống.
Cảm ơn bạn rất nhiều! Than ôi tôi không thể thấy cách định dạng thư mục ban đầu được giữ với mã nén của bạn. Trong ODT tôi sử dụng có các thư mục trống. Theo như tôi hiểu mã của bạn, những thư mục đó sẽ không bao giờ được tạo ra. Tôi có lẽ thiếu một cái gì đó? – Eric
Thư mục là các mục trống với tên kết thúc bằng '/'. Tôi đã thay đổi mã. – McDowell
Tôi đã điều chỉnh cấu trúc mã của bạn và bỏ qua các cuộc gọi đệ quy. Tôi nghĩ đó là một cách sai lầm khi nhìn vào điều này. Mã chạy trơn tru với một ngoại lệ; nó thêm các thư mục rỗng vào hầu hết các thư mục con ngay cả khi chúng không rỗng. Tôi thấy rằng việc xóa dòng sau giải quyết được vấn đề: name = name.endsWith ("/")? name: name + "/"; Tôi nghi ngờ rằng khi thêm một thư mục bằng cách thêm "\" một thư mục cũng tạo ra một thư mục trống bên trong. Bằng cách đơn giản cho phép ZipEntries quản lý cấu trúc, mọi thứ có vẻ ổn. Cảm ơn mọi sự giúp đỡ của bạn! – Eric