我有一个简单的代码来解压缩zip文件,它工作得很好的预期,但我的测试过程中我尽了一些zip文件(字体,图标和模板,我从互联网下载)的代码只是为了确保它应该提取任何zip文件提供的,但它不是用一些zip文件的工作,这里是最小化的代码再生此问题:
package com.test.mytest;
import java.io.FileInputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
public class ZipExtractTest {
public static final String ZIP_FILE = "/Users/XXXXX/Downloads/janne.zip";
public static void main(String[]args) {
unzipFile(ZIP_FILE);
unzipStream(ZIP_FILE);
}
public static void unzipFile(String zipName) {
try {
ZipFile zf = new ZipFile(zipName);
Enumeration ent = zf.entries();
while(ent.hasMoreElements()) {
System.out.println(ent.nextElement());
}
} catch(Exception e) {
System.out.println(e);
}
}
public static void unzipStream(String zipName) {
try {
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipName));
ZipEntry ze = zis.getNextEntry();
if(ze == null) {
System.out.println("unable to get first entry from zip file");
zis.close();
return;
}
while(ze != null) {
System.out.println("Entry Found: " + ze);
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
} catch(Exception e) {
System.out.println(e);
}
}
}
其实在我的实际应用中,我有过inputstreams提取zip文件。 在上面的代码中,我试图提取“janne.zip”我从网上下载该文件http://www.iconian.com/fonts/janne.zip我可以使用任何ZIP工具来提取它令人惊讶的通过“unzipFile (字符串zipName)”的方法为好,但与unzipStream(字符串zipName)方法
ZipEntry ze = zis.getNextEntry();
返回null
任何帮助,将不胜感激
不是一个答案,为什么这个特定的文件不一起工作java.util.zip
,但如果你可以选择更换你的使用java.util.zip.ZipInputStream
与Apache的公地压缩 org.apache.commons.compress.archivers.zip.ZipArchiveInputStream
(这应该是API兼容的),那么我刚刚测试了您的示例文件,它似乎能够成功。
一般来说,我发现公地压缩要远比更可靠java.util.zip
在拆包比其他工具创建的文件java.util.zip
类本身。
编辑:我做了一些调试Eclipse中,它看起来像这个特殊的zip文件中有一个单一的区段跨过标记的0x30304b50
的LOC签名(前0x04034b50
第一入口的地方标头的)。 这是一件公地压缩知道如何处理 ,但java.util.zip
没有-如果juzZipInputStream
看到以外的任何其他一个LOC签名,然后getNextEntry()
将返回null
。
滑稽!
我调试你的代码,并得到了同样的错误。 我发现在ZipInputStream实施的头检查,但不是在zip文件执行。
不要问我为什么,但在你的zip文件的标题是无效的 !
Your file is starting with: 50 4B 30 30 50 4B 03 04
A valid Zip File Header is: 50 4B 03 04
如果删除第一个字节( 50 4B 30 30
从文件)你有一个有效的头一个你可以阅读你的文件!
我有同样的问题! 幸运的是我,我是能够解决这个问题。
第一I RESET在数据库中的二进制大对象数据然后用于Java代码使用ZipInputStream来压缩它。 虽然我不知道,空ZipEntry的问题可能是因为两件事情:
1.在数据库中的BLOB数据没有被正确存储(或可在其已经被压缩,一些数据库压缩在存储时BLOB数据,你可以过google一下)。
2.输入/输出流也可引起麻烦,看到此
下面是我所做的详细介绍:
1.使用EMPTY_BLOB重置blob字段在数据库和提交更改
2.用下面的java程序与.xls文件来更新blob字段
DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver ()); // register driver
Connection conn =
DriverManager.getConnection ("jdbc:oracle:thin:@my-local-database:1521:test", "test1", "test1");
// It's faster when auto commit is off:
conn.setAutoCommit (false);
try
{
PreparedStatement pstmt = conn.prepareStatement("update content set file_content = ? where CONTENT_ID=2006");
File blob = new File("C:/Users/ankur/Desktop/Book1.xls");
FileInputStream in = new FileInputStream(blob);
pstmt.setBinaryStream(1, in);
pstmt.executeUpdate();
conn.commit();
conn.close();
System.out.println("file updated");
}
catch (SQLException e)
{
e.printStackTrace();
}
请注意,上面的代码将工作,但它绝对不能证明编码标准和惯例。
3.用于下面的拉链方法来压缩数据
public byte[] zipByteArray(String primaryKey, byte[] input) throws IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry(primaryKey);
entry.setSize(input.length);
zos.putNextEntry(entry);
zos.write(input);
zos.closeEntry();
zos.close();
return baos.toByteArray();
}
上述方法需要一个字节数组,它拉链,将其放入一个ByteArrayOutputStream。 您可以选择使用ByteArrayOutputStream本身,由于一些要求,我将其转换为字节数组。
4.我然后使用准备语句插入blob字段上述字节数组
5.如果我用下面给出的解压缩代码,它工作正常!
public byte[] unzipInputStream(InputStream is) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = null;
ZipInputStream zipIs = new ZipInputStream(new BufferedInputStream(is));
byteArrayOutputStream = new ByteArrayOutputStream();
ZipEntry entry = zipIs.getNextEntry();
while (entry != null) {
byte[] tmp = new byte[2048];
BufferedOutputStream bos = null;
bos = new BufferedOutputStream(byteArrayOutputStream);
int size = 0;
while ((size = zipIs.read(tmp)) != -1) {
bos.write(tmp, 0, size);
}
bos.flush();
bos.close();
entry = zipIs.getNextEntry();
}
zipIs.close();
return byteArrayOutputStream.toByteArray();
上述方法的输出是将解压缩后的数据。