OutputStream os = new fileOutputStream(zipfile); ZipOutputStream zos = new ZipOutputStream(new bufferedoutputstream(os)); try { zos.setLevel(8); byte[] buffer = new byte[32768]; for (Vfile src : topack) { ZipEntry entry = new ZipEntry(src.name); zos.putNextEntry(entry); src.pushToStream(zos,buffer); src.close(); zos.closeEntry(); } } finally { zos.close(); }
我发现只有一种压缩方法可用 – DEFLATED(只有STORED替代品可用).这意味着始终使用一种方法压缩存档.
如果我在AndroID 2.3.4上运行此代码 – 我可以使用7Zip解压缩windows中的文件;如果我在AndroID 3上运行它(或三星galaxy Tab;不确定谁错了) – 7Zip显示存档列表,但无法解压缩文件说不支持的压缩方法.同时7Zip将Deflate显示为文件上的压缩方法,这意味着它可以正确处理它.
有人有这个问题吗?
谢谢.
UDP:发现另一个topic with similar issue(虽然可能不一样).
解决方法 @ user1269737的答案是正确的;几乎.但它仅适用于单文件存档.下面是一个解析整个存档的代码.
/*** Replace wrong local file header byte* http://sourceforge.net/tracker/?func=detail&aID=3477810&group_ID=14481&atID=114481* ApplIEs to AndroID API 9-13* @param zip file* @throws IOException*/private static voID fixInvalIDZipfile(file zip) throws IOException { RandomAccessfile r = new RandomAccessfile(zip,"rw"); try { long eocd_offset = findEOCDRecord(r); if (eocd_offset > 0) { r.seek(eocd_offset + 16); // offset of first CDE in EOCD long cde_offset = readInt(r); // read offset of first Central Directory Entry long lfh_offset = 0; long fskip,dskip; while (true) { r.seek(cde_offset); if (readInt(r) != CDE_SIGNATURE) // got off sync! return; r.seek(cde_offset + 20); // compressed file size offset fskip = readInt(r); // fix the header // r.seek(lfh_offset + 7); short localFlagsHi = r.readByte(); // hi-order byte of local header flags (general purpose) r.seek(cde_offset + 9); short realFlagsHi = r.readByte(); // hi-order byte of central directory flags (general purpose) if (localFlagsHi != realFlagsHi) { // in latest versions this BUG is fixed,so we're checking is BUG exists. r.seek(lfh_offset + 7); r.write(realFlagsHi); } // calculate offset of next Central Directory Entry // r.seek(cde_offset + 28); // offset of variable CDE parts length in CDE dskip = 46; // length of fixed CDE part dskip += readShort(r); // file name dskip += readShort(r); // extra fIEld dskip += readShort(r); // file comment cde_offset += dskip; if (cde_offset >= eocd_offset) // finished! break; // calculate offset of next Local file header // r.seek(lfh_offset + 26); // offset of variable LFH parts length in LFH fskip += readShort(r); // file name fskip += readShort(r); // extra fIEld fskip += 30; // length of fixed LFH part fskip += 16; // length of Data Descriptor (written after file data) lfh_offset += fskip; } } } finally { r.close(); }}//http://www.pkware.com/documents/casestudIEs/APPNOTE.TXTprivate static final int LFH_SIGNATURE = 0x04034b50;private static final int DD_SIGNATURE = 0x08074b50;private static final int CDE_SIGNATURE = 0x02014b50;private static final int EOCD_SIGNATURE = 0x06054b50;/** Find an offset of End Of Central Directory record in file */private static long findEOCDRecord(RandomAccessfile f) throws IOException{ long result = f.length() - 22; // 22 is minimal EOCD record length while (result > 0) { f.seek(result); if (readInt(f) == EOCD_SIGNATURE) return result; result--; } return -1;}/** Read a 4-byte integer from file converting endianness. */private static int readInt(RandomAccessfile f) throws IOException{ int result = 0; result |= f.read(); result |= (f.read() << 8); result |= (f.read() << 16); result |= (f.read() << 24); return result;}/** Read a 2-byte integer from file converting endianness. */private static short readShort(RandomAccessfile f) throws IOException{ short result = 0; result |= f.read(); result |= (f.read() << 8); return result;}总结
以上是内存溢出为你收集整理的无法从Android上创建的ZIP存档中提取文件(特定于设备/ *** 作系统)全部内容,希望文章能够帮你解决无法从Android上创建的ZIP存档中提取文件(特定于设备/ *** 作系统)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)