@Test public void testUnshrinkEntry() throws Exception { ZipArchiveInputStream in = new ZipArchiveInputStream(new FileInputStream(getFile("SHRUNK.ZIP"))); ZipArchiveEntry entry = in.getNextZipEntry(); assertEquals("method", ZipMethod.UNSHRINKING.getCode(), entry.getMethod()); assertTrue(in.canReadEntryData(entry)); FileInputStream original = new FileInputStream(getFile("test1.xml")); try { assertArrayEquals(IOUtils.toByteArray(original), IOUtils.toByteArray(in)); } finally { original.close(); } entry = in.getNextZipEntry(); assertEquals("method", ZipMethod.UNSHRINKING.getCode(), entry.getMethod()); assertTrue(in.canReadEntryData(entry)); original = new FileInputStream(getFile("test2.xml")); try { assertArrayEquals(IOUtils.toByteArray(original), IOUtils.toByteArray(in)); } finally { original.close(); } }
/** extract zip file */ public void extract(String outputDir) throws IOException { org.apache.commons.compress.archivers.zip.ZipFile file = null; InputStream in = null; OutputStream out = null; try { file = new org.apache.commons.compress.archivers.zip.ZipFile(fileName, fileEncoding); Enumeration<ZipArchiveEntry> entries = file.getEntries(); while (entries.hasMoreElements()) { ZipArchiveEntry entry = entries.nextElement(); String entryName = entry.getName(); if (entry.isDirectory()) { forceMkdir(new File(outputDir + File.separator + entryName)); continue; } out = openOutputStream(new File(outputDir + File.separator + entryName)); in = file.getInputStream(entry); copy(in, out); closeQuietly(in); closeQuietly(out); } } finally { closeQuietly(in); closeQuietly(out); org.apache.commons.compress.archivers.zip.ZipFile.closeQuietly(file); } }
@Test public void testThatExternalAttributesFieldIsFunctional() throws IOException { // Prepare some sample modes to write into the zip file. final ImmutableList<String> samples = ImmutableList.of("rwxrwxrwx", "rw-r--r--", "--x--x--x", "---------"); for (String stringMode : samples) { long mode = MorePosixFilePermissions.toMode(PosixFilePermissions.fromString(stringMode)); // Write a tiny sample zip file, which sets the external attributes per the // permission sample above. try (CustomZipOutputStream out = ZipOutputStreams.newOutputStream(output, OVERWRITE_EXISTING)) { CustomZipEntry entry = new CustomZipEntry("test"); entry.setTime(System.currentTimeMillis()); entry.setExternalAttributes(mode << 16); out.putNextEntry(entry); out.write(new byte[0]); } // Now re-read the zip file using apache's commons-compress, which supports parsing // the external attributes field. try (ZipFile in = new ZipFile(output.toFile())) { Enumeration<ZipArchiveEntry> entries = in.getEntries(); ZipArchiveEntry entry = entries.nextElement(); assertEquals(mode, entry.getExternalAttributes() >> 16); assertFalse(entries.hasMoreElements()); } } }
/** * Overwrite clone. * * @return a cloned copy of this ZipArchiveEntry */ @Override public Object clone() { ZipArchiveEntry e = (ZipArchiveEntry) super.clone(); e.setInternalAttributes(getInternalAttributes()); e.setExternalAttributes(getExternalAttributes()); e.setExtraFields(getAllExtraFieldsNoCopy()); return e; }
/** * Creates a new zip entry with fields taken from the specified zip entry. * * <p>Assumes the entry represents a directory if and only if the name ends with a forward slash * "/". * * @param entry the entry to get fields from * @throws ZipException on error */ public ZipArchiveEntry(ZipArchiveEntry entry) throws ZipException { this((java.util.zip.ZipEntry) entry); setInternalAttributes(entry.getInternalAttributes()); setExternalAttributes(entry.getExternalAttributes()); setExtraFields(getAllExtraFieldsNoCopy()); setPlatform(entry.getPlatform()); GeneralPurposeBit other = entry.getGeneralPurposeBit(); setGeneralPurposeBit(other == null ? null : (GeneralPurposeBit) other.clone()); }
/** Provides default values for compression method and last modification time. */ private void setDefaults(ZipArchiveEntry entry) { if (entry.getMethod() == -1) { // not specified entry.setMethod(method); } if (entry.getTime() == -1) { // not specified entry.setTime(System.currentTimeMillis()); } }
private void extractZipInputStream(final ZipArchiveInputStream in) throws IOException { ZipArchiveEntry zae = in.getNextZipEntry(); while (zae != null) { if (zae.getName().endsWith(".zip")) { extractZipInputStream(new ZipArchiveInputStream(in)); } zae = in.getNextZipEntry(); } }
/** * If the mode is AsNeeded and the entry is a compressed entry of unknown size that gets written * to a non-seekable stream the change the default to Never. * * @since 1.3 */ private Zip64Mode getEffectiveZip64Mode(ZipArchiveEntry ze) { if (zip64Mode != Zip64Mode.AsNeeded || raf != null || ze.getMethod() != DEFLATED || ze.getSize() != ArchiveEntry.SIZE_UNKNOWN) { return zip64Mode; } return Zip64Mode.Never; }
/** * Whether this stream is able to write the given entry. * * <p>May return false if it is set up to use encryption or a compression method that hasn't been * implemented yet. * * @since 1.1 */ @Override public boolean canWriteEntryData(ArchiveEntry ae) { if (ae instanceof ZipArchiveEntry) { ZipArchiveEntry zae = (ZipArchiveEntry) ae; return zae.getMethod() != ZipMethod.IMPLODING.getCode() && zae.getMethod() != ZipMethod.UNSHRINKING.getCode() && ZipUtil.canHandleEntryData(zae); } return false; }
public ZipDirResource(File file) throws IOException { this.zipFile = new ZipFile(file); initialize(); Enumeration<ZipArchiveEntry> entries = zipFile.getEntries(); while (entries.hasMoreElements()) { ZipArchiveEntry zipArchiveEntry = entries.nextElement(); String entryPath = zipArchiveEntry.getName(); createResource(entryPath, zipArchiveEntry); } }
/** * Test case for <a href="https://issues.apache.org/jira/browse/COMPRESS-264" >COMPRESS-264</a>. */ @Test public void testReadingOfFirstStoredEntry() throws Exception { ZipArchiveInputStream in = new ZipArchiveInputStream(new FileInputStream(getFile("COMPRESS-264.zip"))); try { ZipArchiveEntry ze = in.getNextZipEntry(); assertEquals(5, ze.getSize()); assertArrayEquals(new byte[] {'d', 'a', 't', 'a', '\n'}, IOUtils.toByteArray(in)); } finally { in.close(); } }
public void testImplicitPermissions() throws IOException { File zipFile = getTestFile("target/output/zip-with-implicit-dirmode.zip"); ZipArchiver archiver = getZipArchiver(zipFile); archiver.setDefaultDirectoryMode(0777); archiver.setDirectoryMode(0641); archiver.setFileMode(0222); archiver.addFile(new File("pom.xml"), "fizz/buzz/pom.xml"); archiver.setDefaultDirectoryMode(0530); archiver.setDirectoryMode(-1); // Not forced mode archiver.setFileMode(0111); archiver.addFile(new File("pom.xml"), "fazz/bazz/pam.xml"); archiver.createArchive(); assertTrue(zipFile.exists()); ZipFile zf = new ZipFile(zipFile); ZipArchiveEntry fizz = zf.getEntry("fizz/"); assertEquals(040641, fizz.getUnixMode()); ZipArchiveEntry pom = zf.getEntry("fizz/buzz/pom.xml"); assertEquals(0100222, pom.getUnixMode()); ZipArchiveEntry fazz = zf.getEntry("fazz/"); assertEquals(040530, fazz.getUnixMode()); ZipArchiveEntry pam = zf.getEntry("fazz/bazz/pam.xml"); assertEquals(0100111, pam.getUnixMode()); }
/** @see "https://issues.apache.org/jira/browse/COMPRESS-176" */ @Test public void winzipBackSlashWorkaround() throws Exception { ZipArchiveInputStream in = null; try { in = new ZipArchiveInputStream(new FileInputStream(getFile("test-winzip.zip"))); ZipArchiveEntry zae = in.getNextZipEntry(); zae = in.getNextZipEntry(); zae = in.getNextZipEntry(); assertEquals("\u00e4/", zae.getName()); } finally { if (in != null) { in.close(); } } }
@Test public void testUnzipBZip2CompressedEntry() throws Exception { ZipArchiveInputStream in = new ZipArchiveInputStream(new FileInputStream(getFile("bzip2-zip.zip"))); try { ZipArchiveEntry ze = in.getNextZipEntry(); assertEquals(42, ze.getSize()); byte[] expected = new byte[42]; Arrays.fill(expected, (byte) 'a'); assertArrayEquals(expected, IOUtils.toByteArray(in)); } finally { in.close(); } }
@SuppressWarnings("unchecked") private static void unzipFolder(File uncompressFile, File descPathFile, boolean override) { ZipFile zipFile = null; try { zipFile = new ZipFile(uncompressFile, "GBK"); Enumeration<ZipArchiveEntry> entries = zipFile.getEntries(); while (entries.hasMoreElements()) { ZipArchiveEntry zipEntry = entries.nextElement(); String name = zipEntry.getName(); name = name.replace("\\", "/"); File currentFile = new File(descPathFile, name); // 非覆盖 跳过 if (currentFile.isFile() && currentFile.exists() && !override) { continue; } if (name.endsWith("/")) { currentFile.mkdirs(); continue; } else { currentFile.getParentFile().mkdirs(); } FileOutputStream fos = null; try { fos = new FileOutputStream(currentFile); InputStream is = zipFile.getInputStream(zipEntry); IOUtils.copy(is, fos); } finally { IOUtils.closeQuietly(fos); } } } catch (IOException e) { throw new RuntimeException("解压缩失败", e); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException e) { } } } }
/** * If the entry needs Zip64 extra information inside the central directory then configure its * data. */ private void handleZip64Extra(ZipArchiveEntry ze, long lfhOffset, boolean needsZip64Extra) { if (needsZip64Extra) { Zip64ExtendedInformationExtraField z64 = getZip64Extra(ze); if (ze.getCompressedSize() >= ZIP64_MAGIC || ze.getSize() >= ZIP64_MAGIC) { z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize())); z64.setSize(new ZipEightByteInteger(ze.getSize())); } else { // reset value that may have been set for LFH z64.setCompressedSize(null); z64.setSize(null); } if (lfhOffset >= ZIP64_MAGIC) { z64.setRelativeHeaderOffset(new ZipEightByteInteger(lfhOffset)); } ze.setExtra(); } }
public void testOverddidenPermissions() throws IOException { File zipFile = getTestFile("target/output/zip-with-overriden-modes.zip"); ZipArchiver archiver = getZipArchiver(zipFile); archiver.setDefaultDirectoryMode(0777); archiver.setDirectoryMode(0641); archiver.setFileMode(0777); archiver.addDirectory(new File("src/test/resources/symlinks/src")); archiver.createArchive(); assertTrue(zipFile.exists()); ZipFile zf = new ZipFile(zipFile); ZipArchiveEntry fizz = zf.getEntry("symDir"); assertTrue(fizz.isUnixSymlink()); ZipArchiveEntry symR = zf.getEntry("symR"); assertTrue(symR.isUnixSymlink()); }
/** * Grab lists of all root-level files and all directories contained in the given archive. * * @param file . * @param files . * @param dirs . * @throws java.io.IOException . */ protected static void grabFilesAndDirs(String file, List<String> dirs, List<String> files) throws IOException { File zipFile = new File(file); if (!zipFile.exists()) { Logger logger = new ConsoleLogger(Logger.LEVEL_INFO, "console"); logger.error("JarArchive skipping non-existing file: " + zipFile.getAbsolutePath()); } else if (zipFile.isDirectory()) { Logger logger = new ConsoleLogger(Logger.LEVEL_INFO, "console"); logger.info("JarArchiver skipping indexJar " + zipFile + " because it is not a jar"); } else { org.apache.commons.compress.archivers.zip.ZipFile zf = null; try { zf = new org.apache.commons.compress.archivers.zip.ZipFile(file, "utf-8"); Enumeration<ZipArchiveEntry> entries = zf.getEntries(); HashSet<String> dirSet = new HashSet<String>(); while (entries.hasMoreElements()) { ZipArchiveEntry ze = entries.nextElement(); String name = ze.getName(); // avoid index for manifest-only jars. if (!name.equals(META_INF_NAME) && !name.equals(META_INF_NAME + '/') && !name.equals(INDEX_NAME) && !name.equals(MANIFEST_NAME)) { if (ze.isDirectory()) { dirSet.add(name); } else if (!name.contains("/")) { files.add(name); } else { // a file, not in the root // since the jar may be one without directory // entries, add the parent dir of this file as // well. dirSet.add(name.substring(0, name.lastIndexOf("/") + 1)); } } } dirs.addAll(dirSet); } finally { if (zf != null) { zf.close(); } } } }
private void moveNext() { if (in != null) { try { entry = (ZipArchiveEntry) in.getNextEntry(); while (entry != null) { if (!entry.getName().startsWith("_") && !entry.getName().startsWith(".") && isValid(entry.getName())) { next = new FileInputStreamWrapper(FilenameUtils.getName(entry.getName()), in); return; } entry = (ZipArchiveEntry) in.getNextEntry(); } } catch (IOException e) { LOG.warn("Error in zip: " + e); } in.forceClose(); } }
@Override public List<XarEntry> getEntries(File xarFile) throws IOException { List<XarEntry> documents = null; FileInputStream fis = new FileInputStream(xarFile); ZipArchiveInputStream zis = new ZipArchiveInputStream(fis); try { for (ZipArchiveEntry zipEntry = zis.getNextZipEntry(); zipEntry != null; zipEntry = zis.getNextZipEntry()) { if (!zipEntry.isDirectory()) { try { XarPageLimitedHandler documentHandler = new XarPageLimitedHandler(this.componentManager); parseDocument(zis, documentHandler); if (documents == null) { documents = new ArrayList<XarEntry>(); } XarEntry xarEntry = documentHandler.getXarEntry(); xarEntry.setEntryName(zipEntry.getName()); documents.add(xarEntry); } catch (NotADocumentException e) { // Impossible to know that before parsing } catch (Exception e) { this.logger.error("Failed to parse document [" + zipEntry.getName() + "]", e); } } } } finally { zis.close(); } return documents != null ? documents : Collections.<XarEntry>emptyList(); }
/** @see "https://issues.apache.org/jira/browse/COMPRESS-189" */ @Test public void properUseOfInflater() throws Exception { ZipFile zf = null; ZipArchiveInputStream in = null; try { zf = new ZipFile(getFile("COMPRESS-189.zip")); ZipArchiveEntry zae = zf.getEntry("USD0558682-20080101.ZIP"); in = new ZipArchiveInputStream(new BufferedInputStream(zf.getInputStream(zae))); ZipArchiveEntry innerEntry; while ((innerEntry = in.getNextZipEntry()) != null) { if (innerEntry.getName().endsWith("XML")) { assertTrue(0 < in.read()); } } } finally { if (zf != null) { zf.close(); } if (in != null) { in.close(); } } }
/** * Get the existing ZIP64 extended information extra field or create a new one and add it to the * entry. * * @since 1.3 */ private Zip64ExtendedInformationExtraField getZip64Extra(ZipArchiveEntry ze) { if (entry != null) { entry.causedUseOfZip64 = !hasUsedZip64; } hasUsedZip64 = true; Zip64ExtendedInformationExtraField z64 = (Zip64ExtendedInformationExtraField) ze.getExtraField(Zip64ExtendedInformationExtraField.HEADER_ID); if (z64 == null) { /* System.err.println("Adding z64 for " + ze.getName() + ", method: " + ze.getMethod() + " (" + (ze.getMethod() == STORED) + ")" + ", raf: " + (raf != null)); */ z64 = new Zip64ExtendedInformationExtraField(); } // even if the field is there already, make sure it is the first one ze.addAsFirstExtraField(z64); return z64; }
/** * Adds UnicodeExtra fields for name and file comment if mode is ALWAYS or the data cannot be * encoded using the configured encoding. */ private void addUnicodeExtraFields(ZipArchiveEntry ze, boolean encodable, ByteBuffer name) throws IOException { if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS || !encodable) { ze.addExtraField( new UnicodePathExtraField( ze.getName(), name.array(), name.arrayOffset(), name.limit() - name.position())); } String comm = ze.getComment(); if (comm != null && !"".equals(comm)) { boolean commentEncodable = zipEncoding.canEncode(comm); if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS || !commentEncodable) { ByteBuffer commentB = getEntryEncoding(ze).encode(comm); ze.addExtraField( new UnicodeCommentExtraField( comm, commentB.array(), commentB.arrayOffset(), commentB.limit() - commentB.position())); } } }
/** * Writes the data descriptor entry. * * @param ze the entry to write * @throws IOException on error */ protected void writeDataDescriptor(ZipArchiveEntry ze) throws IOException { if (ze.getMethod() != DEFLATED || raf != null) { return; } writeOut(DD_SIG); writeOut(ZipLong.getBytes(ze.getCrc())); int sizeFieldSize = WORD; if (!hasZip64Extra(ze)) { writeOut(ZipLong.getBytes(ze.getCompressedSize())); writeOut(ZipLong.getBytes(ze.getSize())); } else { sizeFieldSize = DWORD; writeOut(ZipEightByteInteger.getBytes(ze.getCompressedSize())); writeOut(ZipEightByteInteger.getBytes(ze.getSize())); } written += 2 * WORD + 2 * sizeFieldSize; }
private void createResource(String path, ZipArchiveEntry entry) { String[] childs = StringUtils.split(path, "/\\"); ZipDirResource res = this; for (int i = 0; i < childs.length - 1; i++) { String name = childs[i]; ZipDirResource child = (ZipDirResource) res.getDir(name); if (child == null) child = new ZipDirResource(res, zipFile); res.addResource(name, child); res = child; } if (entry.isDirectory()) { ZipDirResource child = new ZipDirResource(res, zipFile); child.setEntry(entry); res.addResource(childs[childs.length - 1], child); } else { ZipFileResource child = new ZipFileResource(res, zipFile, entry); res.addResource(childs[childs.length - 1], child); } }
@Override public String getPath() { return entry.getName(); }
/** * Writes the central file header entry. * * @param ze the entry to write * @throws IOException on error * @throws Zip64RequiredException if the archive's size exceeds 4 GByte and {@link Zip64Mode * #setUseZip64} is {@link Zip64Mode#Never}. */ protected void writeCentralFileHeader(ZipArchiveEntry ze) throws IOException { writeOut(CFH_SIG); written += WORD; final long lfhOffset = offsets.get(ze).longValue(); final boolean needsZip64Extra = hasZip64Extra(ze) || ze.getCompressedSize() >= ZIP64_MAGIC || ze.getSize() >= ZIP64_MAGIC || lfhOffset >= ZIP64_MAGIC; if (needsZip64Extra && zip64Mode == Zip64Mode.Never) { // must be the offset that is too big, otherwise an // exception would have been throw in putArchiveEntry or // closeArchiveEntry throw new Zip64RequiredException(Zip64RequiredException.ARCHIVE_TOO_BIG_MESSAGE); } handleZip64Extra(ze, lfhOffset, needsZip64Extra); // version made by // CheckStyle:MagicNumber OFF writeOut( ZipShort.getBytes( (ze.getPlatform() << 8) | (!hasUsedZip64 ? DATA_DESCRIPTOR_MIN_VERSION : ZIP64_MIN_VERSION))); written += SHORT; final int zipMethod = ze.getMethod(); final boolean encodable = zipEncoding.canEncode(ze.getName()); writeVersionNeededToExtractAndGeneralPurposeBits( zipMethod, !encodable && fallbackToUTF8, needsZip64Extra); written += WORD; // compression method writeOut(ZipShort.getBytes(zipMethod)); written += SHORT; // last mod. time and date writeOut(ZipUtil.toDosTime(ze.getTime())); written += WORD; // CRC // compressed length // uncompressed length writeOut(ZipLong.getBytes(ze.getCrc())); if (ze.getCompressedSize() >= ZIP64_MAGIC || ze.getSize() >= ZIP64_MAGIC) { writeOut(ZipLong.ZIP64_MAGIC.getBytes()); writeOut(ZipLong.ZIP64_MAGIC.getBytes()); } else { writeOut(ZipLong.getBytes(ze.getCompressedSize())); writeOut(ZipLong.getBytes(ze.getSize())); } // CheckStyle:MagicNumber OFF written += 12; // CheckStyle:MagicNumber ON ByteBuffer name = getName(ze); writeOut(ZipShort.getBytes(name.limit())); written += SHORT; // extra field length byte[] extra = ze.getCentralDirectoryExtra(); writeOut(ZipShort.getBytes(extra.length)); written += SHORT; // file comment length String comm = ze.getComment(); if (comm == null) { comm = ""; } ByteBuffer commentB = getEntryEncoding(ze).encode(comm); writeOut(ZipShort.getBytes(commentB.limit())); written += SHORT; // disk number start writeOut(ZERO); written += SHORT; // internal file attributes writeOut(ZipShort.getBytes(ze.getInternalAttributes())); written += SHORT; // external file attributes writeOut(ZipLong.getBytes(ze.getExternalAttributes())); written += WORD; // relative offset of LFH writeOut(ZipLong.getBytes(Math.min(lfhOffset, ZIP64_MAGIC))); written += WORD; // file name writeOut(name.array(), name.arrayOffset(), name.limit() - name.position()); written += name.limit(); // extra field writeOut(extra); written += extra.length; // file comment writeOut(commentB.array(), commentB.arrayOffset(), commentB.limit() - commentB.position()); written += commentB.limit(); }
/** * Writes the local file header entry * * @param ze the entry to write * @throws IOException on error */ protected void writeLocalFileHeader(ZipArchiveEntry ze) throws IOException { boolean encodable = zipEncoding.canEncode(ze.getName()); ByteBuffer name = getName(ze); if (createUnicodeExtraFields != UnicodeExtraFieldPolicy.NEVER) { addUnicodeExtraFields(ze, encodable, name); } offsets.put(ze, Long.valueOf(written)); writeOut(LFH_SIG); written += WORD; // store method in local variable to prevent multiple method calls final int zipMethod = ze.getMethod(); writeVersionNeededToExtractAndGeneralPurposeBits( zipMethod, !encodable && fallbackToUTF8, hasZip64Extra(ze)); written += WORD; // compression method writeOut(ZipShort.getBytes(zipMethod)); written += SHORT; // last mod. time and date writeOut(ZipUtil.toDosTime(ze.getTime())); written += WORD; // CRC // compressed length // uncompressed length entry.localDataStart = written; if (zipMethod == DEFLATED || raf != null) { writeOut(LZERO); if (hasZip64Extra(entry.entry)) { // point to ZIP64 extended information extra field for // sizes, may get rewritten once sizes are known if // stream is seekable writeOut(ZipLong.ZIP64_MAGIC.getBytes()); writeOut(ZipLong.ZIP64_MAGIC.getBytes()); } else { writeOut(LZERO); writeOut(LZERO); } } else { writeOut(ZipLong.getBytes(ze.getCrc())); byte[] size = ZipLong.ZIP64_MAGIC.getBytes(); if (!hasZip64Extra(ze)) { size = ZipLong.getBytes(ze.getSize()); } writeOut(size); writeOut(size); } // CheckStyle:MagicNumber OFF written += 12; // CheckStyle:MagicNumber ON // file name length writeOut(ZipShort.getBytes(name.limit())); written += SHORT; // extra field length byte[] extra = ze.getLocalFileDataExtra(); writeOut(ZipShort.getBytes(extra.length)); written += SHORT; // file name writeOut(name.array(), name.arrayOffset(), name.limit() - name.position()); written += name.limit(); // extra field writeOut(extra); written += extra.length; entry.dataStart = written; }
/** * Whether to addd a Zip64 extended information extra field to the local file header. * * <p>Returns true if * * <ul> * <li>mode is Always * <li>or we already know it is going to be needed * <li>or the size is unknown and we can ensure it won't hurt other implementations if we add it * (i.e. we can erase its usage * </ul> */ private boolean shouldAddZip64Extra(ZipArchiveEntry entry, Zip64Mode mode) { return mode == Zip64Mode.Always || entry.getSize() >= ZIP64_MAGIC || entry.getCompressedSize() >= ZIP64_MAGIC || (entry.getSize() == ArchiveEntry.SIZE_UNKNOWN && raf != null && mode != Zip64Mode.Never); }
private ByteBuffer getName(ZipArchiveEntry ze) throws IOException { return getEntryEncoding(ze).encode(ze.getName()); }