📄 jar.java
字号:
/* Program : Jar Use this class to create .zip and .jar files in Java. It should work as a drop in replacement for the JDK's jar program. Copyright : Moses DeJong, dejong@cs.umn.edu, 1998, 2000. Source code licensed under the GPL. You can get a copy of the license from www.gnu.org. This code is intended for use in the Kaffe project but you can use it in other projects as long as you follow the license rules.*/package kaffe.tools.jar;import java.io.*;import java.security.*;import java.util.*;import java.util.jar.*;import java.util.zip.*;import kaffe.io.*;import kaffe.util.Base64;public class Jar { public static void main(String[] argv) { if (debug) { System.out.println("entered Jar.main()"); System.out.flush(); } Jar j = new Jar(argv); j.setExitOnError(true); try { j.start(); } catch (IOException e) { e.printStackTrace(); j.exit(2); } } public Jar(String[] argv) { this.argv = argv; } // Begin processing the command line public void start() throws IOException { // First process the command line arguments so that we know // What mode we are going to be running in. processCommandLine(); processJar(); } public void setExitOnError(boolean exitOnError) { if (exitOnError) { exitCode = 1; } else { exitCode = 0; } } public int getCompletionCode() { return exitCode; } void exit(int code) { if (exitCode != 0) { if (debug) { System.out.println("now exiting with code " + code); System.out.flush(); try { throw new Exception(); } catch (Exception e) { e.printStackTrace(); System.err.flush(); try { Thread.sleep(5000); } catch (Exception e2) {} } } System.out.flush(); System.err.flush(); System.exit(code); } else { exitCode = code; } } void processCommandLine() throws IOException { // Initial set of options tell us if we are extracting or // creating an archive, if zip compressing will be used, // if a manifest will be included and so on. if (debug) { System.out.println("entered Jar.processCommandLine()"); System.out.flush(); } if (argv.length == 0) { printUsage(); exit(1); } // The first argument gives the options to the jar program String options = argv[0]; // This will store where the "next" argv index int options_index = 1; int i = 0; // if the first char is a '-' just ignore it if (options.charAt(0) == '-') { i++; } for (; i < options.length() ; i++) { switch (options.charAt(i)) { case 'c': // Create new archive case 't': // List archive table case 'x': // Extract from archive case 'u': // Update archive // Fall through an process all possible modes if (mode != 0) { printUsage(); exit(1); } mode = options.charAt(i); break; case 'v': // Verbose listing verbose = true; break; case 'f': // Archive file name if (archive != null || options_index >= argv.length) { printUsage(); exit(1); } archive = argv[options_index++]; break; case 'm': // Manifest file name if (manifest != null || options_index >= argv.length || create_manifest == false) { printUsage(); exit(1); } manifest = argv[options_index++]; break; case '0': // Turn off ZIP compression compression = false; break; case 'M': // Do not create a Manifest file in the archive if (manifest != null) { printUsage(); exit(1); } create_manifest = false; break; default: System.out.println("Illegal option: " + options.charAt(i)); printUsage(); exit(1); } } // now get the remaining files that need to be processed // and keep track of any -C (dir change) arguments i = options_index; if ((argv.length - i) > 0) { files = new String[argv.length - i]; for (int j = 0; i < argv.length ; i++, j++) { if (argv[i].equals("-C")) { // Make sure we did not run out of arguments // and that "-C -C" or "-C dir -C" are not given if ((i + 2) >= argv.length || argv[i+1].equals("-C") || argv[i+2].equals("-C")) { printUsage(); exit(1); } i++; if (dir_changes == null) { dir_changes = new String[files.length]; } dir_changes[j] = argv[i]; j--; } else { files[j] = argv[i]; } } // If there were dir changes we must trim the files // so that only valid files are in the array if (dir_changes != null) { for (i=0; i < files.length ; i++) { if (files[i] == null) { break; } } String[] tmp; tmp = files; files = new String[i]; System.arraycopy(tmp,0,files,0,i); tmp = dir_changes; dir_changes = new String[i]; System.arraycopy(tmp,0,dir_changes,0,i); } } // Check to make sure the mode is compatible with the arguments switch (mode) { case 'c': // When creating we must have at least on file argument if (files == null) { System.out.println("'c' flag requires that input files be specified!"); printUsage(); exit(1); } break; case 't': // Listing an archive can have 0 file arguments. // Make sure that no -C options were given when -t is used if (dir_changes != null) { System.out.println("'t' flag can not be used with the -C flag!"); printUsage(); exit(1); } // If archive file name is given then make sure it exists if (archive != null) { XPFile archive_file = new XPFile(archive); if (! archive_file.exists()) { System.out.println("archive \"" + archive_file.getPath() + "\" does not exist"); exit(1); } } break; case 'x': // Extract from archive can have 0 file arguments. // If archive file name is given make sure it exists if (archive != null) { XPFile archive_file = new XPFile(archive); if (! archive_file.exists()) { System.out.println("archive \"" + archive_file.getPath() + "\" does not exist"); exit(1); } } break; case 'u': // Update of archive requires files to update // Update without an archive makes no sense. if (files == null || archive == null) { System.out.println("'u' flag requires that manifest or archive or input files be specified!"); printUsage(); exit(1); } if (archive != null) { XPFile archive_file = new XPFile(archive); if (! archive_file.exists()) { System.out.println("archive \"" + archive_file.getPath() + "\" does not exist"); } exit(1); } break; default: System.out.println("One of the options -{ctxu} must be specified!"); printUsage(); exit(1); } // lookup table must be created after the mode has been checked createFileLookupTable(); if (debug) { dump(); } } void printUsage() { PrintStream o = vout; o.println("Usage: jar {ctxu}[vfm0M] [jar-file] [manifest-file] [-C dir] files ..."); o.println("Options:"); o.print('\t'); o.println("-c create new archive"); o.print('\t'); o.println("-t list table of contents for archive"); o.print('\t'); o.println("-x extract named (or all) files from archive"); o.print('\t'); o.println("-u update existing archive"); o.print('\t'); o.println("-v generate verbose output on standard output"); o.print('\t'); o.println("-f specify archive file name"); o.print('\t'); o.println("-m include manifest information from specified manifest file"); o.print('\t'); o.println("-0 store only; use no ZIP compression"); o.print('\t'); o.println("-M Do not create a manifest file for the entries"); o.print('\t'); o.println("-C change to the specified directory and include the following files"); o.println("If any file is a directory then it is processed recursively."); o.println("The manifest file name and the archive file name needs to be specified"); o.println("in the same order the 'm' and 'f' flags are specified."); o.println(); o.println("Example 1: to archive two class files into an archive called classes.jar:"); o.print('\t'); o.println("jar cvf classes.jar Foo.class Bar.class"); o.println("Example 2: use an existing manifest file 'mymanifest' and archive all the"); o.print('\t'); o.print('\t'); o.println("files in the foo/ directory into 'classes.jar':"); o.print('\t'); o.println("jar cvfm classes.jar mymanifest -C foo/ ."); } void processJar() throws IOException { if (debug) { System.out.println("entered Jar.processCommandLine()"); System.out.println("current mode is " + mode); System.out.flush(); } // Get the current directory switch (mode) { case 'c': createJar(files, absolute_files); exit(0); case 't': listFilesInJar(files); exit(0); case 'x': extractFilesInJar(files, absolute_files); exit(0); case 'u': updateFilesInJar(files, absolute_files); exit(0); default: System.out.println("Unexpected error, '" + mode + "' not matched"); exit(1); } } // Create a table that will map argument file names to // fully qualified file names. void createFileLookupTable() throws IOException { //final boolean debug = true; if (debug) { System.out.println("entered Jar.createFileLookupTable()"); System.out.flush(); } if (files == null) { if (debug) { System.out.println("no files for lookup table"); } return; } File parent = null; File tmp; // File existence requirements for each mode // 'u': Files must exist. // 'x': None // 't': None // 'c': Files must exist. boolean requireExistence = (mode == 'u' || mode == 'c'); boolean existenceError = false; absolute_files = new String[files.length]; for (int i = 0; i < files.length ; i++) { // At this point, make sure that any Windows // Style \ chars in the relative file names are // replaced with unix style / chars so that matching // the file name to the jar entry works. This also // requires that XPFile is used on the file names later. files[i] = files[i].replace('\\','/'); if (dir_changes != null && dir_changes[i] != null) { parent = new XPFile(dir_changes[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -