📄 jar.java
字号:
byte[] digest = dis.getMessageDigest().digest(); attr.putValue(algs[j] + "-Digest", new String(Base64.encode(digest))); if (alglist.length() != 0) { alglist.append(' '); } alglist.append(algs[j]); } if (alglist.length() > 0) { attr.putValue("Digest-Algorithms", alglist.toString()); } } if (debug) { System.out.println("------BEGIN Manifest contents"); jar_manifest.write(System.out); System.out.println("------END Manifest contents"); } jos = new JarOutputStream(out, jar_manifest); if (verbose) { // added manifest vout.println("added manifest"); } } else { // Do not add a manifest when -M cmd line arg is given jos = new JarOutputStream(out); } // now that the Jar stream is open we need to add // each of the file arguments to the stream for (int i=0; i < shortnames.length ; i++) { XPFile infile = new XPFile(longnames[i]); if (infile.isFile()) { // add a regular file to the archive addEntry(jos, shortnames[i], infile); } else { // add a directory and its contents to the archive addEntryDir(jos, shortnames[i], infile); } } } finally { if (jos != null) jos.close(); else out.close(); } } // This is a helper method that adds a single entry to an archive // the entry can be a file or a directory. void addEntry(ZipOutputStream zos, String entryname, XPFile entryfile) throws IOException { // YIKES!! Watch out for the really ugly special case where // we attempt to add the archive that we are writing to the // archive we are writing to the archive we are writing. // You get the idea. There is no way to avoid this case // when writing to stdout. if (archive != null) { XPFile tmp1 = new XPFile(new XPFile(archive).getCanonicalPath()); XPFile tmp2 = new XPFile(entryfile.getCanonicalPath()); if (debug) { System.out.println("archive file is " + archive); System.out.println("entry file is " + entryfile); System.out.println("archiveC file is " + tmp1); System.out.println("entryC file is " + tmp2); } if (tmp1.equals(tmp2)) { if (debug) { System.out.println("avoided adding the archive file"); } return; } } // Make sure the entryname ends with a '/' if it is a directory boolean entryfile_isDirectory = entryfile.isDirectory(); if (entryfile_isDirectory) { if (entryname.length() == 0) { // Something is very wrong here. throw new RuntimeException("entryname was empty"); } if (entryname.charAt( entryname.length() - 1 ) != '/') { entryname = entryname + '/'; } } ZipEntry ze = new ZipEntry(entryname); long entryfile_length = (entryfile_isDirectory ? 0 : entryfile.length()); // Set some entry attributes, take care to make sure that // directory entries are always saved with no compression if (compression && !entryfile_isDirectory) { ze.setMethod(ZipEntry.DEFLATED); // compressed entry } else { ze.setMethod(ZipEntry.STORED); // uncompressed entry ze.setSize(entryfile_length); ze.setCrc( 0 ); // set after stream is read/written to zip } zos.putNextEntry(ze); if (verbose) { // adding: file1 (in=16) (out=18) (deflated -12%) vout.print("adding: " + entryname + " "); vout.print("(in=" + entryfile_length + ") "); } if (!entryfile_isDirectory) { // Write file into the archive, compressing if so requested if (debug) { System.out.println("opening input file \"" + entryfile + "\""); } InputStream in = new XPFileInputStream(entryfile); // This is part of the ugly workaround for a design flaw // in the JDK zip API, for uncompressed entries we // are forced to calculate a CRC for the input stream CRC32 crc = null; if (! compression) { crc = new CRC32(); in = new CheckedInputStream(in,crc); } try { readwriteStreams(in, zos); } finally { in.close(); } // ZIP design flaw workaround if (! compression) { ze.setCrc(crc.getValue()); } } // finish writing the entry to the zip stream // this lets us access the compressed size // attribute of the current ZipEntry zos.closeEntry(); // TEMP CHECK! // If we are writing a directory entry then double // check that we did not actually write any bytes to // the stream. IF we did then something is wrong. if (entryfile_isDirectory) { long tmp; tmp = ze.getSize(); if (tmp != 0) { throw new RuntimeException( "ZipEntry.getSize() for directory was " + tmp + " it should have been 0"); } tmp = ze.getCompressedSize(); if (tmp != 0) { throw new RuntimeException( "ZipEntry.getCompressedSize() for directory was " + tmp + " it should have been 0"); } } if (verbose) { // Find compressed size of entry after it has been added long unsize = ze.getSize(); long csize = ze.getCompressedSize(); // FIXME : if unsize >= 16M then divide unsize and csize by 256 ??? // if (unsize > 0xffffffL) // unsize += 0x80; unsize >>= 8; // csize += 0x80; csize >>= 8; if (debug) { System.out.println("uncompressed size was " + unsize + " " + "compressed size was " + csize); } vout.print("(out=" + csize + ") "); int percent; if (unsize == csize) { percent = 0; } else if (unsize > csize) { // it got smaller percent = Math.round( ((float) (csize) / (float) unsize) * 100.0F ); // if the compressed size if really small call it 99% if (percent == 0) percent = 99; } else { // it got bigger percent = Math.round( ((float) (csize - unsize) / (float) unsize) * -100.0F ); } if (compression && !entryfile_isDirectory) { vout.print("(deflated " + percent + "%)"); } else { vout.print("(stored " + percent + "%)"); } vout.println(); } } // Recursively add directory entries to an archive. This includes // both directories and the files located in those directories. void addEntryDir(ZipOutputStream zos, String entrydirname, XPFile entryfile) throws IOException { if (! entryfile.isDirectory()) { // Something went horribly wrong throw new RuntimeException(entryfile.getPath() + " is not a file and it is not a directory"); } if (debug) { System.out.println("finding files in the directory \"" + entryfile.getPath() + "\""); System.out.println("entrydirname is \"" + entrydirname + "\""); } // add the directory entry to the zip file addEntry(zos, entrydirname, entryfile); // list all the files in the directory String[] files = entryfile.list(); for (int i=0; i < files.length ; i++) { String fname = files[i]; XPFile absfile = new XPFile(entryfile,fname); String relname = new XPFile(entrydirname,fname).getPath(); if (debug) { System.out.println("files[" + i + "] is \"" + fname + "\""); System.out.println(relname + " is a " + (absfile.isFile() ? "File" : "Directory")); System.out.println("relname is \"" + relname + "\""); } if (absfile.isFile()) { addEntry(zos, relname, absfile); } else { addEntryDir(zos, relname, absfile); } } } // This method is used to transfer the contents of input stream to // and output stream. The input stream will be read until EOF is // returned by the read() method. void readwriteStreams(InputStream in, OutputStream out) throws IOException { final boolean debug = false; int numRead; if (debug) { System.out.println("read/write buffer size is " + buffer.length + " bytes"); } while ((numRead = in.read(buffer,0,buffer.length)) != -1) { if (debug) { System.out.println("read " + numRead + " bytes, writing ..."); } out.write(buffer,0,numRead); } } // This method will make sure that all parent directories // for a given file exist. If the parent directories do not // exist then they will be created. void ensureParentsExist(String name) { //final boolean debug = true; if (debug) { System.out.println("making sure parent directory for \"" + name + "\" exists"); } File file = new XPFile(name); String parentString = file.getParent(); if (parentString != null) { File parent = new File(parentString); parent.mkdirs(); } } // Dump the internal contents of the class to stdout void dump() { System.out.println("Called dump()"); for (int i=0; i < argv.length; i++) { System.out.println("argv[" + i + "] is \"" + argv[i] + "\""); } System.out.println("manifest is \"" + manifest + "\""); System.out.println("create_manifest is \"" + create_manifest + "\""); System.out.println("archive is \"" + archive + "\""); System.out.println("compression is \"" + compression + "\""); System.out.println("verbose is \"" + verbose + "\""); System.out.println("mode is \"" + mode + "\""); if (files == null) { System.out.println("no files"); } else { System.out.println(files.length + " files to process"); for (int i=0; i < files.length; i++) { System.out.println("files[" + i + "] is \"" + files[i] + "\""); } } if (dir_changes == null) { System.out.println("no dir changes"); } else { for (int i=0; i < files.length; i++) { System.out.println("dir_changes[" + i + "] is \"" + dir_changes[i] + "\""); } } if (absolute_files == null) { System.out.println("no absolute file names"); } else { for (int i=0; i < absolute_files.length; i++) { System.out.println("absolute_files[" + i + "] is \"" + absolute_files[i] + "\""); } } /* System.out.println(" is \"" + + "\""); System.out.println(" is \"" + + "\""); System.out.println(" is \"" + + "\""); */ } // command line arguments String[] argv; // The file name of a manifest file String manifest = null; // If no manifest should be added to an archive this is false boolean create_manifest = true; // The file name of the archive, null if none was given with -f String archive = null; // Files to be added, updated, or extracted from the archive // If no files were given these will be null String[] files; String[] absolute_files; // non null directory change name, cd is done at i'th index in files String[] dir_changes; // True if we are in verbose output mode boolean verbose = false; // True if created archive should be compressed boolean compression = true; // One of 't' (list), 'c' (create), 'x' (extract), or 'u' (update) char mode = (char) 0; // Non zero if System.exit() is allowed int exitCode = 0; // Size of read write buffers we will use final int bufferSize = 8 * 1024; // The actual read write buffer final byte[] buffer = new byte[bufferSize]; // set to true to see extra debug output final static boolean debug = false; // stream where verbose output will be going PrintStream vout = System.out;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -