下面列出了怎么用java.util.zip.ZipFile的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Read who;e zip item into byte array.
*
* @param zipFile zip file
* @param path path to resource
* @return byte array or null if not found
* @throws IOException thrown if there is any transport error
*/
@Nullable
public static byte[] toByteArray(@Nonnull final ZipFile zipFile, @Nonnull final String path) throws IOException {
final InputStream in = findInputStreamForResource(zipFile, path);
byte[] result = null;
if (in != null) {
try {
result = IOUtils.toByteArray(in);
} finally {
IOUtils.closeQuietly(in);
}
}
return result;
}
/**
* Create a new song pack from a file.
*
* @param file the file to create the song pack from.
* @return the song pack that's been created
* @throws IOException if something went wrong.
*/
public static SongPack fromFile(File file) throws IOException {
try (ZipFile zipFile = new ZipFile(file, Charset.forName("UTF-8"))) {
SongPack ret = new SongPack();
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
try {
ZipEntry entry = entries.nextElement();
SongDisplayable song = SongDisplayable.parseXML(zipFile.getInputStream(entry));
if (song != null) {
ret.addSong(song);
}
} catch (Exception ex) {
//Skipping malformed song...
}
}
return ret;
}
}
public static void main(String args[]) throws Exception {
createZipFile();
try (ZipFile zf = new ZipFile(new File(ZIPFILE_NAME))) {
is = zf.getInputStream(zf.getEntry(ZIPENTRY_NAME));
Thread[] threadArray = new Thread[NUM_THREADS];
for (int i = 0; i < threadArray.length; i++) {
threadArray[i] = new MultiThreadedReadTest();
}
for (int i = 0; i < threadArray.length; i++) {
threadArray[i].start();
}
for (int i = 0; i < threadArray.length; i++) {
threadArray[i].join();
}
} finally {
FileUtils.deleteFileIfExistsWithRetry(Paths.get(ZIPFILE_NAME));
}
}
/**
* Scans given archive for files passing given filter, adds the results into given list.
*/
private void handleArchiveByFile(Predicate<String> filter, File archive, List<String> discoveredFiles)
{
try
{
try (ZipFile zip = new ZipFile(archive))
{
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements())
{
ZipEntry entry = entries.nextElement();
String name = entry.getName();
if (filter.accept(name))
discoveredFiles.add(name);
}
}
}
catch (IOException e)
{
throw new RuntimeException("Error handling file " + archive, e);
}
}
/**
* Populates class and resource maps.
*
* @throws IOException
* Thrown if the archive could not be read, or an internal file
* could not be read.
*/
protected Map<String, byte[]> readArchive() throws IOException {
Map<String, byte[]> contents = new HashMap<>();
try (ZipFile file = new ZipFile(jarFile)) {
// iterate zip entries
Enumeration<? extends ZipEntry> entries = file.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
// skip directories
if (entry.isDirectory()) continue;
try (InputStream is = file.getInputStream(entry)) {
// add as class, or resource if not a class file.
String name = entry.getName();
if (name.endsWith(".class")) {
addClass(name, is);
} else {
addResource(name, is);
}
}
}
}
return contents;
}
/** @return open a completely new input stream to the given resource (to avoid sharing a single zip file.) */
public InputStream openNew() {
try {
if (zipContainer) {
final ZipFile zf = new ZipFile(container);
final InputStream in = zf.getInputStream(zf.getEntry(fileName));
BufferedInputStream bin = new BufferedInputStream(in) {
@Override
public void close() throws IOException {
super.close();
zf.close();
}
};
return bin;
}
return new FileInputStream(container + "/" + fileName);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
/**
* unpack...
*
* @param zip the zip
* @param patchDir the patch dir
* @throws IOException
*/
private static void unzip(final ZipFile zip, final File patchDir) throws IOException {
final Enumeration<? extends ZipEntry> entries = zip.entries();
while(entries.hasMoreElements()) {
final ZipEntry entry = entries.nextElement();
final String name = entry.getName();
final File current = new File(patchDir, name);
if(entry.isDirectory()) {
continue;
} else {
if(! current.getParentFile().exists()) {
current.getParentFile().mkdirs();
}
try (final InputStream eis = zip.getInputStream(entry)){
Files.copy(eis, current.toPath());
//copy(eis, current);
}
}
}
}
private static boolean unzipChildFile(final File destDir,
final List<File> files,
final ZipFile zip,
final ZipEntry entry,
final String name) throws IOException {
File file = new File(destDir, name);
files.add(file);
if (entry.isDirectory()) {
return createOrExistsDir(file);
} else {
if (!createOrExistsFile(file)) return false;
try (InputStream in = new BufferedInputStream(zip.getInputStream(entry)); OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
byte buffer[] = new byte[BUFFER_LEN];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
}
return true;
}
/**
* Creates a new dex buffer from the dex file {@code file}.
*/
public Dex(File file) throws IOException{
if (FileUtils.hasArchiveSuffix(file.getName())) {
ZipFile zipFile = new ZipFile(file);
ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);
if (entry != null) {
loadFrom(zipFile.getInputStream(entry));
zipFile.close();
} else {
throw new DexException2("Expected " + DexFormat.DEX_IN_JAR_NAME + " in " + file);
}
} else if (file.getName().endsWith(".dex")) {
loadFrom(new FileInputStream(file));
} else {
throw new DexException2("unknown output extension: " + file);
}
}
private static ZipFile getZipFile(URL url) {
try {
URI uri = url.toURI();
File file = new File(uri);
ZipFile zipFile = new ZipFile(file);
if (zipFile.getEntry("eu/the5zig/mod/The5zigMod.class") == null) {
zipFile.close();
return null;
}
return zipFile;
} catch (Exception ignored) {
return null;
}
}
/** CLI wrapper to run against every class in a set of JARs. */
public static void main(String[] args) throws IOException {
ImmutableSet.Builder<DalvikMemberReference> allFields = ImmutableSet.builder();
for (String fname : args) {
try (ZipFile inJar = new ZipFile(fname)) {
for (ZipEntry entry : Collections.list(inJar.entries())) {
if (!entry.getName().endsWith(".class")) {
continue;
}
InputStream rawClass = inJar.getInputStream(entry);
Stats stats = getEstimate(rawClass);
System.out.println(
stats.estimatedLinearAllocSize + "\t" + entry.getName().replace(".class", ""));
allFields.addAll(stats.fieldReferences);
}
}
}
// Uncomment to debug fields.
// System.out.println();
//
// for (DalvikMemberReference field : allFields.build()) {
// System.out.println(field);
// }
}
@Test
public void testMultipleModulesWithInstallTime_bundleToolVersionOverride() throws Exception {
XmlNode installTimeModuleManifest =
androidManifestForFeature("com.test.app.detail", withInstallTimeDelivery());
createBasicZipBuilder(BUNDLE_CONFIG_0_14_0)
.addFileWithProtoContent(ZipPath.create("base/manifest/AndroidManifest.xml"), MANIFEST)
.addFileWithContent(ZipPath.create("base/dex/classes.dex"), DUMMY_CONTENT)
.addFileWithContent(ZipPath.create("base/assets/baseAssetfile.txt"), DUMMY_CONTENT)
.addFileWithProtoContent(
ZipPath.create("detail/manifest/AndroidManifest.xml"), installTimeModuleManifest)
.addFileWithContent(ZipPath.create("detail/assets/detailsAssetfile.txt"), DUMMY_CONTENT)
.writeTo(bundleFile);
try (ZipFile appBundleZip = new ZipFile(bundleFile.toFile())) {
AppBundle appBundle =
BundleModuleMerger.mergeNonRemovableInstallTimeModules(
AppBundle.buildFromZip(appBundleZip), /* overrideBundleToolVersion = */ true);
assertThat(appBundle.getFeatureModules().keySet())
.comparingElementsUsing(equalsBundleModuleName())
.containsExactly("base");
}
}
private boolean installBundle(ZipFile zipFile, String location, Application application) {
log.info("processLibsBundle entryName " + location);
this.bundleDebug.installExternalBundle(location);
String fileNameFromEntryName = Utils.getFileNameFromEntryName(location);
String packageNameFromEntryName = Utils.getPackageNameFromEntryName(location);
if (packageNameFromEntryName == null || packageNameFromEntryName.length() <= 0) {
return false;
}
File archvieFile = new File(new File(application.getFilesDir().getParentFile(), "lib"), fileNameFromEntryName);
if (OpenAtlas.getInstance().getBundle(packageNameFromEntryName) != null) {
return false;
}
try {
if (archvieFile.exists()) {
OpenAtlas.getInstance().installBundle(packageNameFromEntryName, archvieFile);
} else {
OpenAtlas.getInstance().installBundle(packageNameFromEntryName, zipFile.getInputStream(zipFile.getEntry(location)));
}
log.info("Succeed to install bundle " + packageNameFromEntryName);
return true;
} catch (Throwable e) {
Log.e("BundlesInstaller", "Could not install bundle.", e);
return false;
}
}
@Override
public void parse(File file) throws IOException {
mZipFile = new ZipFile(file.getAbsolutePath());
mEntries = new ArrayList<ZipEntry>();
Enumeration<? extends ZipEntry> e = mZipFile.entries();
while (e.hasMoreElements()) {
ZipEntry ze = e.nextElement();
if (!ze.isDirectory() && Utils.isImage(ze.getName())) {
mEntries.add(ze);
}
}
Collections.sort(mEntries, new NaturalOrderComparator() {
@Override
public String stringValue(Object o) {
return ((ZipEntry) o).getName();
}
});
}
/**
* Creates a new dex buffer from the dex file {@code file}.
*/
public Dex(File file) throws IOException {
if (FileUtils.hasArchiveSuffix(file.getName())) {
ZipFile zipFile = new ZipFile(file);
ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);
if (entry != null) {
try (InputStream inputStream = zipFile.getInputStream(entry)) {
loadFrom(inputStream);
}
zipFile.close();
} else {
throw new DexException("Expected " + DexFormat.DEX_IN_JAR_NAME + " in " + file);
}
} else if (file.getName().endsWith(".dex")) {
try (InputStream inputStream = new FileInputStream(file)) {
loadFrom(inputStream);
}
} else {
throw new DexException("unknown output extension: " + file);
}
}
private static void runTest(int compression) throws Exception {
ReferenceQueue<InputStream> rq = new ReferenceQueue<>();
System.out.println("Testing with a zip file with compression level = "
+ compression);
File f = createTestFile(compression);
try (ZipFile zf = new ZipFile(f)) {
Set<Object> refSet = createTransientInputStreams(zf, rq);
System.out.println("Waiting for 'stale' input streams from ZipFile to be GC'd ...");
System.out.println("(The test will hang on failure)");
while (false == refSet.isEmpty()) {
refSet.remove(rq.remove());
}
System.out.println("Test PASSED.");
System.out.println();
} finally {
f.delete();
}
}
private static void verifyZipFile(String name, String comment)
throws Exception
{
// Check that Zip entry was correctly written.
try (ZipFile zipFile = new ZipFile(name)) {
ZipEntry zipEntry = zipFile.getEntry(entryName);
InputStream is = zipFile.getInputStream(zipEntry);
String result = new DataInputStream(is).readUTF();
if (!result.equals(entryContents))
throw new Exception("Entry contents corrupted");
}
try (RandomAccessFile file = new RandomAccessFile(name, "r")) {
// Check that comment length was correctly written.
file.seek(file.length() - comment.length()
- ZipFile.ENDHDR + ZipFile.ENDCOM);
int b1 = file.readUnsignedByte();
int b2 = file.readUnsignedByte();
if (b1 + (b2 << 8) != comment.length())
throw new Exception("Zip file comment length corrupted");
// Check that comment was correctly written.
file.seek(file.length() - comment.length());
byte [] bytes = new byte [comment.length()];
file.readFully(bytes);
if (! comment.equals(new String(bytes, "UTF8")))
throw new Exception("Zip file comment corrupted");
}
}
private static void install(ClassLoader loader, List<File> additionalClassPathEntries)
throws IllegalArgumentException, IllegalAccessException,
NoSuchFieldException, IOException {
/* The patched class loader is expected to be a descendant of
* dalvik.system.DexClassLoader. We modify its
* fields mPaths, mFiles, mZips and mDexs to append additional DEX
* file entries.
*/
int extraSize = additionalClassPathEntries.size();
Field pathField = RocooUtils.findField(loader, "path");
StringBuilder path = new StringBuilder((String) pathField.get(loader));
String[] extraPaths = new String[extraSize];
File[] extraFiles = new File[extraSize];
ZipFile[] extraZips = new ZipFile[extraSize];
DexFile[] extraDexs = new DexFile[extraSize];
for (ListIterator<File> iterator = additionalClassPathEntries.listIterator();
iterator.hasNext(); ) {
File additionalEntry = iterator.next();
String entryPath = additionalEntry.getAbsolutePath();
path.append(':').append(entryPath);
int index = iterator.previousIndex();
extraPaths[index] = entryPath;
extraFiles[index] = additionalEntry;
extraZips[index] = new ZipFile(additionalEntry);
extraDexs[index] = DexFile.loadDex(entryPath, entryPath + ".dex", 0);
}
pathField.set(loader, path.toString());
RocooUtils.expandFieldArray(loader, "mPaths", extraPaths);
RocooUtils.expandFieldArray(loader, "mFiles", extraFiles);
RocooUtils.expandFieldArray(loader, "mZips", extraZips);
RocooUtils.expandFieldArray(loader, "mDexs", extraDexs);
}
private ZipEntry getZipEntryImpl(String path)
throws IOException
{
if (path.startsWith("/")) {
path = path.substring(1);
}
boolean isValid = false;
ZipFile zipFile = getZipFile();
try {
if (zipFile != null) {
ZipEntry entry = zipFile.getEntry(path);
isValid = true;
return entry;
}
else
return null;
} finally {
if (isValid)
closeZipFile(zipFile);
else if (zipFile != null)
zipFile.close();
}
}
/**
* Given a File input it will unzip the file in a the unzip directory
* passed as the second parameter
* @param inFile The zip file as input
* @param unzipDir The unzip directory where to unzip the zip file.
* @throws IOException
*/
public static void unZip(File inFile, File unzipDir) throws IOException {
Enumeration<? extends ZipEntry> entries;
ZipFile zipFile = new ZipFile(inFile);
try {
entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
InputStream in = zipFile.getInputStream(entry);
try {
File file = new File(unzipDir, entry.getName());
if (!file.getParentFile().mkdirs()) {
if (!file.getParentFile().isDirectory()) {
throw new IOException("Mkdirs failed to create " +
file.getParentFile().toString());
}
}
OutputStream out = new FileOutputStream(file);
try {
byte[] buffer = new byte[8192];
int i;
while ((i = in.read(buffer)) != -1) {
out.write(buffer, 0, i);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
} finally {
zipFile.close();
}
}
/**
* Return the files' comment in ZIP file.
*
* @param zipFile The ZIP file.
* @return the files' comment in ZIP file
* @throws IOException if an I/O error has occurred
*/
public static List<String> getComments(final File zipFile)
throws IOException {
if (zipFile == null) return null;
List<String> comments = new ArrayList<>();
ZipFile zip = new ZipFile(zipFile);
Enumeration<?> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
comments.add(entry.getComment());
}
zip.close();
return comments;
}
public ZippedResourcePack(File file) {
if (!file.exists()) {
throw new IllegalArgumentException(Server.getInstance().getLanguage()
.translateString("nukkit.resources.zip.not-found", file.getName()));
}
this.file = file;
try {
ZipFile zip = new ZipFile(file);
ZipEntry entry = zip.getEntry("manifest.json");
if (entry == null) {
zip.close();
throw new IllegalArgumentException(Server.getInstance().getLanguage()
.translateString("nukkit.resources.zip.no-manifest"));
} else {
this.manifest = new JsonParser()
.parse(new InputStreamReader(zip.getInputStream(entry), StandardCharsets.UTF_8))
.getAsJsonObject();
}
zip.close();
} catch (IOException e) {
Server.getInstance().getLogger().logException(e);
}
if (!this.verifyManifest()) {
throw new IllegalArgumentException(Server.getInstance().getLanguage()
.translateString("nukkit.resources.zip.invalid-manifest"));
}
}
private static String getChecksum(ZipFile zf) {
// checksum should ignore time/date stamps on files - just look at entries and contents. also ignore order.
// (tests fail without time/date is one reason, but really if a person rebuilds a ZIP that is the same
// files we should treat it as identical)
try {
Map<String,String> entriesToChecksum = MutableMap.of();
for (ZipEntry ze: Collections.list(zf.entries())) {
entriesToChecksum.put(ze.getName(), Streams.getMd5Checksum(zf.getInputStream(ze)));
}
return Streams.getMd5Checksum(Streams.newInputStreamWithContents(new TreeMap<>(entriesToChecksum).toString()));
} catch (Exception e) {
throw Exceptions.propagate(e);
}
}
/**
* Appends CRC codes of all the files in the .zip archive to the hash.
*/
private void hashZipEntries(ZipFile zipFile) {
ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE / 8);
Enumeration<? extends ZipEntry> enumeration = zipFile.entries();
while (enumeration.hasMoreElements()) {
ZipEntry entry = enumeration.nextElement();
hash.update(entry.getName().getBytes(UTF_8));
buffer.putLong(0, entry.getCrc());
hash.update(buffer.array());
}
}
/** Extract the .apks files from a zip file containing multiple .apks files. */
private static ImmutableList<Path> extractApksFromZip(Path zipPath, TempDirectory tempDirectory)
throws IOException {
ImmutableList.Builder<Path> extractedApks = ImmutableList.builder();
Path zipExtractedSubDirectory = tempDirectory.getPath().resolve("extracted");
Files.createDirectory(zipExtractedSubDirectory);
try (ZipFile apksArchiveContainer = new ZipFile(zipPath.toFile())) {
ImmutableList<ZipEntry> apksToExtractList =
apksArchiveContainer.stream()
.filter(
zipEntry ->
!zipEntry.isDirectory()
&& zipEntry.getName().toLowerCase(Locale.ROOT).endsWith(".apks"))
.collect(toImmutableList());
for (ZipEntry apksToExtract : apksToExtractList) {
Path extractedApksPath =
zipExtractedSubDirectory.resolve(
ZipPath.create(apksToExtract.getName()).getFileName().toString());
try (InputStream inputStream = apksArchiveContainer.getInputStream(apksToExtract);
OutputStream outputApks = Files.newOutputStream(extractedApksPath)) {
ByteStreams.copy(inputStream, outputApks);
extractedApks.add(extractedApksPath);
}
}
}
return extractedApks.build();
}
/**
* Given a File input it will unzip the file in a the unzip directory
* passed as the second parameter
* @param inFile The zip file as input
* @param unzipDir The unzip directory where to unzip the zip file.
* @throws IOException
*/
public static void unZip(File inFile, File unzipDir) throws IOException {
Enumeration<? extends ZipEntry> entries;
ZipFile zipFile = new ZipFile(inFile);
try {
entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
InputStream in = zipFile.getInputStream(entry);
try {
File file = new File(unzipDir, entry.getName());
if (!file.getParentFile().mkdirs()) {
if (!file.getParentFile().isDirectory()) {
throw new IOException("Mkdirs failed to create " +
file.getParentFile().toString());
}
}
OutputStream out = new FileOutputStream(file);
try {
byte[] buffer = new byte[8192];
int i;
while ((i = in.read(buffer)) != -1) {
out.write(buffer, 0, i);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
} finally {
zipFile.close();
}
}
private void addArchive(String path, File file, int type, boolean isOwn) throws IOException {
try (ZipFile archive = type == ContextUnit.TYPE_JAR ? new JarFile(file) : new ZipFile(file)) {
Enumeration<? extends ZipEntry> entries = archive.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
ContextUnit unit = units.get(path + "/" + file.getName());
if (unit == null) {
unit = new ContextUnit(type, path, file.getName(), isOwn, saver, decompiledData);
if (type == ContextUnit.TYPE_JAR) {
unit.setManifest(((JarFile) archive).getManifest());
}
units.put(path + "/" + file.getName(), unit);
}
String name = entry.getName();
if (!entry.isDirectory()) {
if (name.endsWith(".class")) {
byte[] bytes = InterpreterUtil.getBytes(archive, entry);
StructClass cl = new StructClass(bytes, isOwn, loader);
classes.put(cl.qualifiedName, cl);
unit.addClass(cl, name);
loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(file.getAbsolutePath(), name));
} else {
unit.addOtherEntry(file.getAbsolutePath(), name);
}
} else {
unit.addDirEntry(name);
}
}
}
}
private int getStreamSizeFromComment(String fileToImport) {
int ret = 1;
try {
ZipFile zipFile = new ZipFile(fileToImport);
String comment = zipFile.getComment();
ret = processZipFileStreamSizeComment(comment);
zipFile.close();
} catch (IOException e) {
LOG.error("Error opening ZIP file: {}", fileToImport, e);
}
return ret;
}
private void writeEntry(ZipFile zf, ZipOutputStream os, ZipEntry ze)
throws IOException {
ZipEntry ze2 = new ZipEntry(ze.getName());
ze2.setMethod(ze.getMethod());
ze2.setTime(ze.getTime());
ze2.setComment(ze.getComment());
ze2.setExtra(ze.getExtra());
if (ze.getMethod() == ZipEntry.STORED) {
ze2.setSize(ze.getSize());
ze2.setCrc(ze.getCrc());
}
os.putNextEntry(ze2);
writeBytes(zf, ze, os);
}
@Override
protected Map<String, byte[]> loadClasses() throws IOException {
// iterate jar entries
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
EntryLoader loader = getEntryLoader();
try (ZipFile zipFile = new ZipFile(getPath().toFile())) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while(entries.hasMoreElements()) {
// verify entries are classes and valid files
// - skip intentional garbage / zip file abnormalities
ZipEntry entry = entries.nextElement();
if (shouldSkip(entry.getName()))
continue;
if(!loader.isValidClassEntry(entry))
continue;
if(!loader.isValidFileEntry(entry))
continue;
out.reset();
InputStream stream = zipFile.getInputStream(entry);
byte[] in = IOUtil.toByteArray(stream, out, buffer);
loader.onClass(entry.getName(), in);
}
}
loader.finishClasses();
return loader.getClasses();
}