📄 zip.java
字号:
String prefix = ""; String fullpath = ""; int dirMode = ArchiveFileSet.DEFAULT_DIR_MODE; int fileMode = ArchiveFileSet.DEFAULT_FILE_MODE; ArchiveFileSet zfs = null; if (fileset instanceof ArchiveFileSet) { zfs = (ArchiveFileSet) fileset; prefix = zfs.getPrefix(getProject()); fullpath = zfs.getFullpath(getProject()); dirMode = zfs.getDirMode(getProject()); fileMode = zfs.getFileMode(getProject()); } if (prefix.length() > 0 && fullpath.length() > 0) { throw new BuildException("Both prefix and fullpath attributes must" + " not be set on the same fileset."); } if (resources.length != 1 && fullpath.length() > 0) { throw new BuildException("fullpath attribute may only be specified" + " for filesets that specify a single" + " file."); } if (prefix.length() > 0) { if (!prefix.endsWith("/") && !prefix.endsWith("\\")) { prefix += "/"; } addParentDirs(null, prefix, zOut, "", dirMode); } ZipFile zf = null; try { boolean dealingWithFiles = false; File base = null; if (zfs == null || zfs.getSrc(getProject()) == null) { dealingWithFiles = true; base = fileset.getDir(getProject()); } else if (zfs instanceof ZipFileSet) { zf = new ZipFile(zfs.getSrc(getProject()), encoding); } for (int i = 0; i < resources.length; i++) { String name = null; if (fullpath.length() > 0) { name = fullpath; } else { name = resources[i].getName(); } name = name.replace(File.separatorChar, '/'); if ("".equals(name)) { continue; } if (resources[i].isDirectory() && !name.endsWith("/")) { name = name + "/"; } if (!doFilesonly && !dealingWithFiles && resources[i].isDirectory() && !zfs.hasDirModeBeenSet()) { int nextToLastSlash = name.lastIndexOf("/", name.length() - 2); if (nextToLastSlash != -1) { addParentDirs(base, name.substring(0, nextToLastSlash + 1), zOut, prefix, dirMode); } if (zf != null) { ZipEntry ze = zf.getEntry(resources[i].getName()); addParentDirs(base, name, zOut, prefix, ze.getUnixMode()); } else { ArchiveResource tr = (ArchiveResource) resources[i]; addParentDirs(base, name, zOut, prefix, tr.getMode()); } } else { addParentDirs(base, name, zOut, prefix, dirMode); } if (!resources[i].isDirectory() && dealingWithFiles) { File f = FILE_UTILS.resolveFile(base, resources[i].getName()); zipFile(f, zOut, prefix + name, fileMode); } else if (!resources[i].isDirectory()) { if (zf != null) { ZipEntry ze = zf.getEntry(resources[i].getName()); if (ze != null) { boolean oldCompress = doCompress; if (keepCompression) { doCompress = (ze.getMethod() == ZipEntry.DEFLATED); } InputStream is = null; try { is = zf.getInputStream(ze); zipFile(is, zOut, prefix + name, ze.getTime(), zfs.getSrc(getProject()), zfs.hasFileModeBeenSet() ? fileMode : ze.getUnixMode()); } finally { doCompress = oldCompress; FileUtils.close(is); } } } else { ArchiveResource tr = (ArchiveResource) resources[i]; InputStream is = null; try { is = tr.getInputStream(); zipFile(is, zOut, prefix + name, resources[i].getLastModified(), zfs.getSrc(getProject()), zfs.hasFileModeBeenSet() ? fileMode : tr.getMode()); } finally { FileUtils.close(is); } } } } } finally { if (zf != null) { zf.close(); } } } /** * Add the given resources. * * @param rc may give additional information like fullpath or * permissions. * @param resources the resources to add * @param zOut the stream to write to * @throws IOException on error * * @since Ant 1.7 */ protected final void addResources(ResourceCollection rc, Resource[] resources, ZipOutputStream zOut) throws IOException { if (rc instanceof FileSet) { addResources((FileSet) rc, resources, zOut); return; } for (int i = 0; i < resources.length; i++) { String name = resources[i].getName().replace(File.separatorChar, '/'); if ("".equals(name)) { continue; } if (resources[i].isDirectory() && doFilesonly) { continue; } File base = null; if (resources[i] instanceof FileResource) { base = ((FileResource) resources[i]).getBaseDir(); } if (resources[i].isDirectory()) { if (!name.endsWith("/")) { name = name + "/"; } } addParentDirs(base, name, zOut, "", ArchiveFileSet.DEFAULT_DIR_MODE); if (!resources[i].isDirectory()) { if (resources[i] instanceof FileResource) { File f = ((FileResource) resources[i]).getFile(); zipFile(f, zOut, name, ArchiveFileSet.DEFAULT_FILE_MODE); } else { InputStream is = null; try { is = resources[i].getInputStream(); zipFile(is, zOut, name, resources[i].getLastModified(), null, ArchiveFileSet.DEFAULT_FILE_MODE); } finally { FileUtils.close(is); } } } } } /** * method for subclasses to override * @param zOut the zip output stream * @throws IOException on output error * @throws BuildException on other errors */ protected void initZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { } /** * method for subclasses to override * @param zOut the zip output stream * @throws IOException on output error * @throws BuildException on other errors */ protected void finalizeZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { } /** * Create an empty zip file * @param zipFile the zip file * @return true for historic reasons * @throws BuildException on error */ protected boolean createEmptyZip(File zipFile) throws BuildException { // In this case using java.util.zip will not work // because it does not permit a zero-entry archive. // Must create it manually. log("Note: creating empty " + archiveType + " archive " + zipFile, Project.MSG_INFO); OutputStream os = null; try { os = new FileOutputStream(zipFile); // CheckStyle:MagicNumber OFF // Cf. PKZIP specification. byte[] empty = new byte[22]; empty[0] = 80; // P empty[1] = 75; // K empty[2] = 5; empty[3] = 6; // remainder zeros // CheckStyle:MagicNumber ON os.write(empty); } catch (IOException ioe) { throw new BuildException("Could not create empty ZIP archive " + "(" + ioe.getMessage() + ")", ioe, getLocation()); } finally { FileUtils.close(os); } return true; } /** * @since Ant 1.5.2 */ private synchronized ZipScanner getZipScanner() { if (zs == null) { zs = new ZipScanner(); zs.setEncoding(encoding); zs.setSrc(zipFile); } return zs; } /** * Collect the resources that are newer than the corresponding * entries (or missing) in the original archive. * * <p>If we are going to recreate the archive instead of updating * it, all resources should be considered as new, if a single one * is. Because of this, subclasses overriding this method must * call <code>super.getResourcesToAdd</code> and indicate with the * third arg if they already know that the archive is * out-of-date.</p> * * <p>This method first delegates to getNonFileSetResourceToAdd * and then invokes the FileSet-arg version. All this to keep * backwards compatibility for subclasses that don't know how to * deal with non-FileSet ResourceCollections.</p> * * @param rcs The resource collections to grab resources from * @param zipFile intended archive file (may or may not exist) * @param needsUpdate whether we already know that the archive is * out-of-date. Subclasses overriding this method are supposed to * set this value correctly in their call to * <code>super.getResourcesToAdd</code>. * @return an array of resources to add for each fileset passed in as well * as a flag that indicates whether the archive is uptodate. * * @exception BuildException if it likes * @since Ant 1.7 */ protected ArchiveState getResourcesToAdd(ResourceCollection[] rcs, File zipFile, boolean needsUpdate) throws BuildException { ArrayList filesets = new ArrayList(); ArrayList rest = new ArrayList(); for (int i = 0; i < rcs.length; i++) { if (rcs[i] instanceof FileSet) { filesets.add(rcs[i]); } else { rest.add(rcs[i]); } } ResourceCollection[] rc = (ResourceCollection[]) rest.toArray(new ResourceCollection[rest.size()]); ArchiveState as = getNonFileSetResourcesToAdd(rc, zipFile, needsUpdate); FileSet[] fs = (FileSet[]) filesets.toArray(new FileSet[filesets .size()]); ArchiveState as2 = getResourcesToAdd(fs, zipFile, as.isOutOfDate()); if (!as.isOutOfDate() && as2.isOutOfDate()) { /* * Bad luck. * * There are resources in the filesets that make the * archive out of date, but not in the non-fileset * resources. We need to rescan the non-FileSets to grab * all of them now. */ as = getNonFileSetResourcesToAdd(rc, zipFile, true); } Resource[][] toAdd = new Resource[rcs.length][]; int fsIndex = 0; int restIndex = 0; for (int i = 0; i < rcs.length; i++) { if (rcs[i] instanceof FileSet) { toAdd[i] = as2.getResourcesToAdd()[fsIndex++]; } else { toAdd[i] = as.getResourcesToAdd()[restIndex++]; } } return new ArchiveState(as2.isOutOfDate(), toAdd); } /** * Collect the resources that are newer than the corresponding * entries (or missing) in the original archive. * * <p>If we are going to recreate the archive instead of updating * it, all resources should be considered as new, if a single one * is. Because of this, subclasses overriding this method must * call <code>super.getResourcesToAdd</code> and indicate with the * third arg if they already know that the archive is * out-of-date.</p> * * @param filesets The filesets to grab resources from * @param zipFile intended archive file (may or may not exist) * @param needsUpdate whether we already know that the archive is * out-of-date. Subclasses overriding this method are supposed to * set this value correctly in their call to * <code>super.getResourcesToAdd</code>. * @return an array of resources to add for each fileset passed in as well * as a flag that indicates whether the archive is uptodate.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -