6332094: "jar t" and "jar x" should use ZipFile, not ZipInputStream
To use ZipFile for jar "t" and "x" to boost performance Reviewed-by: martin, alanb
This commit is contained in:
parent
9298831bab
commit
4a82a1723e
@ -74,7 +74,6 @@ class Main {
|
|||||||
static final String MANIFEST = JarFile.MANIFEST_NAME;
|
static final String MANIFEST = JarFile.MANIFEST_NAME;
|
||||||
static final String MANIFEST_DIR = "META-INF/";
|
static final String MANIFEST_DIR = "META-INF/";
|
||||||
static final String VERSION = "1.0";
|
static final String VERSION = "1.0";
|
||||||
static final char SEPARATOR = File.separatorChar;
|
|
||||||
static final String INDEX = JarIndex.INDEX_NAME;
|
static final String INDEX = JarIndex.INDEX_NAME;
|
||||||
|
|
||||||
private static ResourceBundle rsrc;
|
private static ResourceBundle rsrc;
|
||||||
@ -227,19 +226,32 @@ class Main {
|
|||||||
}
|
}
|
||||||
tmpFile.delete();
|
tmpFile.delete();
|
||||||
}
|
}
|
||||||
} else if (xflag || tflag) {
|
} else if (tflag) {
|
||||||
InputStream in;
|
replaceFSC(files);
|
||||||
if (fname != null) {
|
if (fname != null) {
|
||||||
in = new FileInputStream(fname);
|
list(fname, files);
|
||||||
} else {
|
} else {
|
||||||
in = new FileInputStream(FileDescriptor.in);
|
InputStream in = new FileInputStream(FileDescriptor.in);
|
||||||
|
try{
|
||||||
|
list(new BufferedInputStream(in), files);
|
||||||
|
} finally {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (xflag) {
|
} else if (xflag) {
|
||||||
extract(new BufferedInputStream(in), files);
|
replaceFSC(files);
|
||||||
|
if (fname != null && files != null) {
|
||||||
|
extract(fname, files);
|
||||||
} else {
|
} else {
|
||||||
list(new BufferedInputStream(in), files);
|
InputStream in = (fname == null)
|
||||||
|
? new FileInputStream(FileDescriptor.in)
|
||||||
|
: new FileInputStream(fname);
|
||||||
|
try {
|
||||||
|
extract(new BufferedInputStream(in), files);
|
||||||
|
} finally {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
in.close();
|
|
||||||
} else if (iflag) {
|
} else if (iflag) {
|
||||||
genIndex(rootjar, files);
|
genIndex(rootjar, files);
|
||||||
}
|
}
|
||||||
@ -760,6 +772,31 @@ class Main {
|
|||||||
e.setCrc(crc32.getValue());
|
e.setCrc(crc32.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void replaceFSC(String files[]) {
|
||||||
|
if (files != null) {
|
||||||
|
for (String file : files) {
|
||||||
|
file = file.replace(File.separatorChar, '/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<ZipEntry> newDirSet() {
|
||||||
|
return new HashSet<ZipEntry>() {
|
||||||
|
public boolean add(ZipEntry e) {
|
||||||
|
return ((e == null || useExtractionTime) ? false : super.add(e));
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateLastModifiedTime(Set<ZipEntry> zes) throws IOException {
|
||||||
|
for (ZipEntry ze : zes) {
|
||||||
|
long lastModified = ze.getTime();
|
||||||
|
if (lastModified != -1) {
|
||||||
|
File f = new File(ze.getName().replace('/', File.separatorChar));
|
||||||
|
f.setLastModified(lastModified);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extracts specified entries from JAR file.
|
* Extracts specified entries from JAR file.
|
||||||
*/
|
*/
|
||||||
@ -768,19 +805,13 @@ class Main {
|
|||||||
ZipEntry e;
|
ZipEntry e;
|
||||||
// Set of all directory entries specified in archive. Disallows
|
// Set of all directory entries specified in archive. Disallows
|
||||||
// null entries. Disallows all entries if using pre-6.0 behavior.
|
// null entries. Disallows all entries if using pre-6.0 behavior.
|
||||||
Set<ZipEntry> dirs = new HashSet<ZipEntry>() {
|
Set<ZipEntry> dirs = newDirSet();
|
||||||
public boolean add(ZipEntry e) {
|
|
||||||
return ((e == null || useExtractionTime) ? false : super.add(e));
|
|
||||||
}};
|
|
||||||
|
|
||||||
while ((e = zis.getNextEntry()) != null) {
|
while ((e = zis.getNextEntry()) != null) {
|
||||||
if (files == null) {
|
if (files == null) {
|
||||||
dirs.add(extractFile(zis, e));
|
dirs.add(extractFile(zis, e));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String name = e.getName();
|
String name = e.getName();
|
||||||
for (int i = 0; i < files.length; i++) {
|
for (String file : files) {
|
||||||
String file = files[i].replace(File.separatorChar, '/');
|
|
||||||
if (name.startsWith(file)) {
|
if (name.startsWith(file)) {
|
||||||
dirs.add(extractFile(zis, e));
|
dirs.add(extractFile(zis, e));
|
||||||
break;
|
break;
|
||||||
@ -793,13 +824,33 @@ class Main {
|
|||||||
// timestamps as given in the archive. We do this after extraction,
|
// timestamps as given in the archive. We do this after extraction,
|
||||||
// instead of during, because creating a file in a directory changes
|
// instead of during, because creating a file in a directory changes
|
||||||
// that directory's timestamp.
|
// that directory's timestamp.
|
||||||
for (ZipEntry dirEntry : dirs) {
|
updateLastModifiedTime(dirs);
|
||||||
long lastModified = dirEntry.getTime();
|
}
|
||||||
if (lastModified != -1) {
|
|
||||||
File dir = new File(dirEntry.getName().replace('/', File.separatorChar));
|
/*
|
||||||
dir.setLastModified(lastModified);
|
* Extracts specified entries from JAR file, via ZipFile.
|
||||||
|
*/
|
||||||
|
void extract(String fname, String files[]) throws IOException {
|
||||||
|
ZipFile zf = new ZipFile(fname);
|
||||||
|
Set<ZipEntry> dirs = newDirSet();
|
||||||
|
Enumeration<? extends ZipEntry> zes = zf.entries();
|
||||||
|
while (zes.hasMoreElements()) {
|
||||||
|
ZipEntry e = zes.nextElement();
|
||||||
|
InputStream is;
|
||||||
|
if (files == null) {
|
||||||
|
dirs.add(extractFile(zf.getInputStream(e), e));
|
||||||
|
} else {
|
||||||
|
String name = e.getName();
|
||||||
|
for (String file : files) {
|
||||||
|
if (name.startsWith(file)) {
|
||||||
|
dirs.add(extractFile(zf.getInputStream(e), e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zf.close();
|
||||||
|
updateLastModifiedTime(dirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -807,7 +858,7 @@ class Main {
|
|||||||
* the entry is for a directory which doesn't exist prior to this
|
* the entry is for a directory which doesn't exist prior to this
|
||||||
* invocation, returns that entry, otherwise returns null.
|
* invocation, returns that entry, otherwise returns null.
|
||||||
*/
|
*/
|
||||||
ZipEntry extractFile(ZipInputStream zis, ZipEntry e) throws IOException {
|
ZipEntry extractFile(InputStream is, ZipEntry e) throws IOException {
|
||||||
ZipEntry rc = null;
|
ZipEntry rc = null;
|
||||||
String name = e.getName();
|
String name = e.getName();
|
||||||
File f = new File(e.getName().replace('/', File.separatorChar));
|
File f = new File(e.getName().replace('/', File.separatorChar));
|
||||||
@ -838,13 +889,19 @@ class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
OutputStream os = new FileOutputStream(f);
|
OutputStream os = new FileOutputStream(f);
|
||||||
byte[] b = new byte[512];
|
byte[] b = new byte[8192];
|
||||||
int len;
|
int len;
|
||||||
while ((len = zis.read(b, 0, b.length)) != -1) {
|
try {
|
||||||
os.write(b, 0, len);
|
while ((len = is.read(b, 0, b.length)) != -1) {
|
||||||
|
os.write(b, 0, len);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (is instanceof ZipInputStream)
|
||||||
|
((ZipInputStream)is).closeEntry();
|
||||||
|
else
|
||||||
|
is.close();
|
||||||
|
os.close();
|
||||||
}
|
}
|
||||||
zis.closeEntry();
|
|
||||||
os.close();
|
|
||||||
if (vflag) {
|
if (vflag) {
|
||||||
if (e.getMethod() == ZipEntry.DEFLATED) {
|
if (e.getMethod() == ZipEntry.DEFLATED) {
|
||||||
output(formatMsg("out.inflated", name));
|
output(formatMsg("out.inflated", name));
|
||||||
@ -869,7 +926,6 @@ class Main {
|
|||||||
ZipInputStream zis = new ZipInputStream(in);
|
ZipInputStream zis = new ZipInputStream(in);
|
||||||
ZipEntry e;
|
ZipEntry e;
|
||||||
while ((e = zis.getNextEntry()) != null) {
|
while ((e = zis.getNextEntry()) != null) {
|
||||||
String name = e.getName();
|
|
||||||
/*
|
/*
|
||||||
* In the case of a compressed (deflated) entry, the entry size
|
* In the case of a compressed (deflated) entry, the entry size
|
||||||
* is stored immediately following the entry data and cannot be
|
* is stored immediately following the entry data and cannot be
|
||||||
@ -877,20 +933,22 @@ class Main {
|
|||||||
* the entry first before printing out its attributes.
|
* the entry first before printing out its attributes.
|
||||||
*/
|
*/
|
||||||
zis.closeEntry();
|
zis.closeEntry();
|
||||||
if (files == null) {
|
printEntry(e, files);
|
||||||
printEntry(e);
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
|
||||||
String file = files[i].replace(File.separatorChar, '/');
|
|
||||||
if (name.startsWith(file)) {
|
|
||||||
printEntry(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lists contents of JAR file, via ZipFile.
|
||||||
|
*/
|
||||||
|
void list(String fname, String files[]) throws IOException {
|
||||||
|
ZipFile zf = new ZipFile(fname);
|
||||||
|
Enumeration<? extends ZipEntry> zes = zf.entries();
|
||||||
|
while (zes.hasMoreElements()) {
|
||||||
|
printEntry(zes.nextElement(), files);
|
||||||
|
}
|
||||||
|
zf.close();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output the class index table to the INDEX.LIST file of the
|
* Output the class index table to the INDEX.LIST file of the
|
||||||
* root jar file.
|
* root jar file.
|
||||||
@ -974,13 +1032,29 @@ class Main {
|
|||||||
dumpIndex(rootjar, index);
|
dumpIndex(rootjar, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prints entry information, if requested.
|
||||||
|
*/
|
||||||
|
void printEntry(ZipEntry e, String[] files) throws IOException {
|
||||||
|
if (files == null) {
|
||||||
|
printEntry(e);
|
||||||
|
} else {
|
||||||
|
String name = e.getName();
|
||||||
|
for (String file : files) {
|
||||||
|
if (name.startsWith(file)) {
|
||||||
|
printEntry(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prints entry information.
|
* Prints entry information.
|
||||||
*/
|
*/
|
||||||
void printEntry(ZipEntry e) throws IOException {
|
void printEntry(ZipEntry e) throws IOException {
|
||||||
if (vflag) {
|
if (vflag) {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuilder sb = new StringBuilder();
|
||||||
String s = Long.toString(e.getSize());
|
String s = Long.toString(e.getSize());
|
||||||
for (int i = 6 - s.length(); i > 0; --i) {
|
for (int i = 6 - s.length(); i > 0; --i) {
|
||||||
sb.append(' ');
|
sb.append(' ');
|
||||||
|
Loading…
Reference in New Issue
Block a user