下面列出了java.util.zip.DeflaterInputStream#libcore.io.Streams 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Verifies the compatibility entry from an {@link InputStream}.
*
* @return the verification result.
*/
private static boolean verifyPackageCompatibility(InputStream inputStream) throws IOException {
ArrayList<String> list = new ArrayList<>();
ZipInputStream zis = new ZipInputStream(inputStream);
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
long entrySize = entry.getSize();
if (entrySize > Integer.MAX_VALUE || entrySize < 0) {
throw new IOException(
"invalid entry size (" + entrySize + ") in the compatibility file");
}
byte[] bytes = new byte[(int) entrySize];
Streams.readFully(zis, bytes);
list.add(new String(bytes, UTF_8));
}
if (list.isEmpty()) {
throw new IOException("no entries found in the compatibility file");
}
return (VintfObject.verify(list.toArray(new String[list.size()])) == 0);
}
private void readAndVerifyDataDescriptor(int inB, int out) throws IOException {
if (hasDD) {
Streams.readFully(in, hdrBuf, 0, EXTHDR);
int sig = Memory.peekInt(hdrBuf, 0, true);
if (sig != (int) EXTSIG) {
throw new ZipException(String.format("unknown format (EXTSIG=%x)", sig));
}
currentEntry.crc = ((long) Memory.peekInt(hdrBuf, EXTCRC, true)) & 0xffffffffL;
currentEntry.compressedSize = ((long) Memory.peekInt(hdrBuf, EXTSIZ, true)) & 0xffffffffL;
currentEntry.size = ((long) Memory.peekInt(hdrBuf, EXTLEN, true)) & 0xffffffffL;
}
if (currentEntry.crc != crc.getValue()) {
throw new ZipException("CRC mismatch");
}
if (currentEntry.compressedSize != inB || currentEntry.size != out) {
throw new ZipException("Size mismatch");
}
}
/**
* Merges name/attribute pairs read from the input stream {@code is} into this manifest.
*
* @param is
* The {@code InputStream} to read from.
* @throws IOException
* If an error occurs reading the manifest.
*/
public void read(InputStream is) throws IOException {
byte[] buf;
if (is instanceof ByteArrayInputStream) {
buf = exposeByteArrayInputStreamBytes((ByteArrayInputStream) is);
} else {
buf = Streams.readFullyNoClose(is);
}
if (buf.length == 0) {
return;
}
// a workaround for HARMONY-5662
// replace EOF and NUL with another new line
// which does not trigger an error
byte b = buf[buf.length - 1];
if (b == 0 || b == 26) {
buf[buf.length - 1] = '\n';
}
ManifestReader im = new ManifestReader(buf, mainAttributes);
mainEnd = im.getEndOfMainSection();
im.readEntries(entries, chunks);
}
public void testRead_golden() throws Exception {
try (DeflaterInputStream dis = new DeflaterInputStream(is)) {
byte[] contents = Streams.readFully(dis);
assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, contents));
}
try (DeflaterInputStream dis = new DeflaterInputStream(
new ByteArrayInputStream(TEST_STR.getBytes("UTF-8")))) {
byte[] result = new byte[32];
int count = 0;
int bytesRead;
while ((bytesRead = dis.read(result, count, 4)) != -1) {
count += bytesRead;
}
assertEquals(23, count);
byte[] splicedResult = new byte[23];
System.arraycopy(result, 0, splicedResult, 0, 23);
assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, splicedResult));
}
}
@Override
protected void setUp() throws Exception {
// Create a local copy of the file since some tests want to alter
// information.
final File f = File.createTempFile("ZipEntryTest", ".zip");
InputStream is = Support_Resources.getStream("hyts_ZipFile.zip");
FileOutputStream fos = new java.io.FileOutputStream(f);
Streams.copy(is, fos);
is.close();
fos.close();
zfile = new ZipFile(f);
zentry = zfile.getEntry("File1.txt");
orgSize = zentry.getSize();
orgCompressedSize = zentry.getCompressedSize();
orgCrc = zentry.getCrc();
orgTime = zentry.getTime();
}
private String readFile(Context context, int resourceId) {
try{
InputStream stream = context.getResources().openRawResource(resourceId);
return new String(Streams.readFully(new InputStreamReader(stream)));
}
catch (IOException e) {
Slog.e(TAG, "Unrecognized shader " + Integer.toString(resourceId));
throw new RuntimeException(e);
}
}
private byte[] getAltContent(Context c, Intent i) throws IOException {
Uri content = getContentFromIntent(i);
InputStream is = c.getContentResolver().openInputStream(content);
try {
return Streams.readFullyNoClose(is);
} finally {
is.close();
}
}
private HashMap<String, byte[]> getMetaEntries() throws IOException {
HashMap<String, byte[]> metaEntries = new HashMap<String, byte[]>();
Iterator<ZipEntry> entryIterator = new EntryIterator(nativeHandle, "META-INF/");
while (entryIterator.hasNext()) {
final ZipEntry entry = entryIterator.next();
metaEntries.put(entry.getName(), Streams.readFully(getInputStream(entry)));
}
return metaEntries;
}
public void testRead_leavesBufUnmodified() throws Exception {
DeflaterInputStreamWithPublicBuffer dis = new DeflaterInputStreamWithPublicBuffer(is);
byte[] contents = Streams.readFully(dis);
assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, contents));
// protected field buf is a part of the public API of this class.
// we guarantee that it's only used as an input buffer, and not for
// anything else.
byte[] buf = dis.getBuffer();
byte[] expected = TEST_STR.getBytes("UTF-8");
byte[] splicedBuf = new byte[expected.length];
System.arraycopy(buf, 0, splicedBuf, 0, splicedBuf.length);
assertTrue(Arrays.equals(expected, splicedBuf));
}
@Override
protected void setUp() throws IOException {
// Create a local copy of the file since some tests want to alter information.
File tempFile = File.createTempFile("OldZipFileTest", "zip");
tempFileName = tempFile.getAbsolutePath();
InputStream is = Support_Resources.getStream("hyts_ZipFile.zip");
FileOutputStream fos = new FileOutputStream(tempFile);
Streams.copy(is, fos);
is.close();
fos.close();
zfile = new ZipFile(tempFile);
}
public void testAvailable() throws Exception {
// NOTE: We don't care about the contents of any of these entries as long as they're
// not empty.
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(
zip(new String[] { "foo", "bar", "baz" }, new byte[] { 0, 0, 0, 1, 1, 1 })));
assertEquals(1, zis.available());
zis.getNextEntry();
assertEquals(1, zis.available());
zis.closeEntry();
// On Android M and below, this call would return "1". That seems a bit odd given that the
// contract for available states that we should return 1 if there are any bytes left to read
// from the "current" entry.
assertEquals(0, zis.available());
// There shouldn't be any bytes left to read if the entry is fully consumed...
zis.getNextEntry();
Streams.readFullyNoClose(zis);
assertEquals(0, zis.available());
// ... or if the entry is fully skipped over.
zis.getNextEntry();
zis.skip(Long.MAX_VALUE);
assertEquals(0, zis.available());
// There are no entries left in the file, so there whould be nothing left to read.
assertNull(zis.getNextEntry());
assertEquals(0, zis.available());
zis.close();
}
private int runSnapshotProfile() throws RemoteException {
PrintWriter pw = getOutPrintWriter();
// Parse the arguments
final String packageName = getNextArg();
final boolean isBootImage = "android".equals(packageName);
String codePath = null;
String opt;
while ((opt = getNextArg()) != null) {
switch (opt) {
case "--code-path":
if (isBootImage) {
pw.write("--code-path cannot be used for the boot image.");
return -1;
}
codePath = getNextArg();
break;
default:
pw.write("Unknown arg: " + opt);
return -1;
}
}
// If no code path was explicitly requested, select the base code path.
String baseCodePath = null;
if (!isBootImage) {
PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
/* userId */0);
if (packageInfo == null) {
pw.write("Package not found " + packageName);
return -1;
}
baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
if (codePath == null) {
codePath = baseCodePath;
}
}
// Create the profile snapshot.
final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
// The calling package is needed to debug permission access.
final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
? "root" : "com.android.shell";
final int profileType = isBootImage
? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
pw.println("Error: Runtime profiling is not enabled");
return -1;
}
mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
codePath, callback, callingPackage);
if (!callback.waitTillDone()) {
pw.println("Error: callback not called");
return callback.mErrCode;
}
// Copy the snapshot profile to the output profile file.
try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
? "" : ("-" + new File(codePath).getName());
final String outputProfilePath =
ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
Streams.copy(inStream, outStream);
}
// Give read permissions to the other group.
Os.chmod(outputProfilePath, /*mode*/ 0644 );
} catch (IOException | ErrnoException e) {
pw.println("Error when reading the profile fd: " + e.getMessage());
e.printStackTrace(pw);
return -1;
}
return 0;
}
@Override
public void write(int oneByte) throws IOException {
Streams.writeSingleByte(this, oneByte);
}
@Override
public long skip(long byteCount) throws IOException {
return Streams.skipByReading(this, byteCount);
}
@Override public int read() throws IOException {
return Streams.readSingleByte(this);
}
protected static void executeShellCommand(String command) throws IOException {
InputStream is = new FileInputStream(InstrumentationRegistry.getInstrumentation()
.getUiAutomation().executeShellCommand(command).getFileDescriptor());
Streams.readFully(is);
}
@Override
public void write(int i) throws IOException {
Streams.writeSingleByte(this, i);
}
/**
* Returns the next entry from this {@code ZipInputStream} or {@code null} if
* no more entries are present.
*
* @throws IOException if an {@code IOException} occurs.
*/
public ZipEntry getNextEntry() throws IOException {
closeEntry();
if (entriesEnd) {
return null;
}
// Read the signature to see whether there's another local file header.
Streams.readFully(in, hdrBuf, 0, 4);
int hdr = Memory.peekInt(hdrBuf, 0, true);
if (hdr == CENSIG) {
entriesEnd = true;
return null;
}
if (hdr != LOCSIG) {
return null;
}
// Read the local file header.
Streams.readFully(in, hdrBuf, 0, (LOCHDR - LOCVER));
int version = peekShort(0) & 0xff;
if (version > ZIPLocalHeaderVersionNeeded) {
throw new ZipException("Cannot read local header version " + version);
}
int flags = peekShort(LOCFLG - LOCVER);
if ((flags & ZipFile.GPBF_UNSUPPORTED_MASK) != 0) {
throw new ZipException("Invalid General Purpose Bit Flag: " + flags);
}
hasDD = ((flags & ZipFile.GPBF_DATA_DESCRIPTOR_FLAG) != 0);
int ceLastModifiedTime = peekShort(LOCTIM - LOCVER);
int ceLastModifiedDate = peekShort(LOCTIM - LOCVER + 2);
int ceCompressionMethod = peekShort(LOCHOW - LOCVER);
long ceCrc = 0, ceCompressedSize = 0, ceSize = -1;
if (!hasDD) {
ceCrc = ((long) Memory.peekInt(hdrBuf, LOCCRC - LOCVER, true)) & 0xffffffffL;
ceCompressedSize = ((long) Memory.peekInt(hdrBuf, LOCSIZ - LOCVER, true)) & 0xffffffffL;
ceSize = ((long) Memory.peekInt(hdrBuf, LOCLEN - LOCVER, true)) & 0xffffffffL;
}
int nameLength = peekShort(LOCNAM - LOCVER);
if (nameLength == 0) {
throw new ZipException("Entry is not named");
}
int extraLength = peekShort(LOCEXT - LOCVER);
if (nameLength > nameBuf.length) {
nameBuf = new byte[nameLength];
// The bytes are modified UTF-8, so the number of chars will always be less than or
// equal to the number of bytes. It's fine if this buffer is too long.
}
Streams.readFully(in, nameBuf, 0, nameLength);
currentEntry = createZipEntry(ModifiedUtf8.decode(nameBuf, 0, nameLength));
currentEntry.time = ceLastModifiedTime;
currentEntry.modDate = ceLastModifiedDate;
currentEntry.setMethod(ceCompressionMethod);
if (ceSize != -1) {
currentEntry.setCrc(ceCrc);
currentEntry.setSize(ceSize);
currentEntry.setCompressedSize(ceCompressedSize);
}
if (extraLength > 0) {
byte[] extraData = new byte[extraLength];
Streams.readFully(in, extraData, 0, extraLength);
currentEntry.setExtra(extraData);
}
return currentEntry;
}
ZipEntry(byte[] cdeHdrBuf, InputStream cdStream) throws IOException {
Streams.readFully(cdStream, cdeHdrBuf, 0, cdeHdrBuf.length);
BufferIterator it = HeapBufferIterator.iterator(cdeHdrBuf, 0, cdeHdrBuf.length,
ByteOrder.LITTLE_ENDIAN);
int sig = it.readInt();
if (sig != CENSIG) {
ZipFile.throwZipException("Central Directory Entry", sig);
}
it.seek(8);
int gpbf = it.readShort() & 0xffff;
if ((gpbf & ZipFile.GPBF_UNSUPPORTED_MASK) != 0) {
throw new ZipException("Invalid General Purpose Bit Flag: " + gpbf);
}
compressionMethod = it.readShort() & 0xffff;
time = it.readShort() & 0xffff;
modDate = it.readShort() & 0xffff;
// These are 32-bit values in the file, but 64-bit fields in this object.
crc = ((long) it.readInt()) & 0xffffffffL;
compressedSize = ((long) it.readInt()) & 0xffffffffL;
size = ((long) it.readInt()) & 0xffffffffL;
nameLength = it.readShort() & 0xffff;
int extraLength = it.readShort() & 0xffff;
int commentByteCount = it.readShort() & 0xffff;
// This is a 32-bit value in the file, but a 64-bit field in this object.
it.seek(42);
localHeaderRelOffset = ((long) it.readInt()) & 0xffffffffL;
byte[] nameBytes = new byte[nameLength];
Streams.readFully(cdStream, nameBytes, 0, nameBytes.length);
if (containsNulByte(nameBytes)) {
throw new ZipException("Filename contains NUL byte: " + Arrays.toString(nameBytes));
}
name = new String(nameBytes, 0, nameBytes.length, StandardCharsets.UTF_8);
if (extraLength > 0) {
extra = new byte[extraLength];
Streams.readFully(cdStream, extra, 0, extraLength);
}
// The RI has always assumed UTF-8. (If GPBF_UTF8_FLAG isn't set, the encoding is
// actually IBM-437.)
if (commentByteCount > 0) {
byte[] commentBytes = new byte[commentByteCount];
Streams.readFully(cdStream, commentBytes, 0, commentByteCount);
comment = new String(commentBytes, 0, commentBytes.length, StandardCharsets.UTF_8);
}
}
/**
* {@inheritDoc}
* <p>Note: if {@code n > Integer.MAX_VALUE}, this stream will only attempt to
* skip {@code Integer.MAX_VALUE} bytes.
*/
@Override
public long skip(long byteCount) throws IOException {
byteCount = Math.min(Integer.MAX_VALUE, byteCount);
return Streams.skipByReading(this, byteCount);
}
@Override public int read() throws IOException {
return Streams.readSingleByte(this);
}
public final void readFully(byte[] dst, int offset, int byteCount) throws IOException {
Streams.readFully(in, dst, offset, byteCount);
}
public final int readInt() throws IOException {
Streams.readFully(in, scratch, 0, SizeOf.INT);
return Memory.peekInt(scratch, 0, ByteOrder.BIG_ENDIAN);
}
public final long readLong() throws IOException {
Streams.readFully(in, scratch, 0, SizeOf.LONG);
return Memory.peekLong(scratch, 0, ByteOrder.BIG_ENDIAN);
}
public final short readShort() throws IOException {
Streams.readFully(in, scratch, 0, SizeOf.SHORT);
return Memory.peekShort(scratch, 0, ByteOrder.BIG_ENDIAN);
}
/**
* Skips up to {@code byteCount} bytes of uncompressed data.
*
* @param byteCount the number of bytes to skip.
* @return the number of uncompressed bytes skipped.
* @throws IllegalArgumentException if {@code byteCount < 0}.
* @throws IOException if an error occurs skipping.
*/
@Override
public long skip(long byteCount) throws IOException {
if (byteCount < 0) {
throw new IllegalArgumentException("byteCount < 0");
}
return Streams.skipByReading(this, byteCount);
}
/**
* Creates a new {@code StrictJarManifest} instance using the attributes obtained
* from the input stream.
*
* @param is
* {@code InputStream} to parse for attributes.
* @throws IOException
* if an IO error occurs while creating this {@code StrictJarManifest}
*/
public StrictJarManifest(InputStream is) throws IOException {
this();
read(Streams.readFully(is));
}
/**
* Merges name/attribute pairs read from the input stream {@code is} into this manifest.
*
* @param is
* The {@code InputStream} to read from.
* @throws IOException
* If an error occurs reading the manifest.
*/
public void read(InputStream is) throws IOException {
read(Streams.readFullyNoClose(is));
}
/**
* Reads a single byte of decompressed data.
*
* @return the byte read.
* @throws IOException
* if an error occurs reading the byte.
*/
@Override
public int read() throws IOException {
return Streams.readSingleByte(this);
}
/**
* Reads a byte from the compressed input stream. The result will be a byte of compressed
* data corresponding to an uncompressed byte or bytes read from the underlying stream.
*
* @return the byte or -1 if the end of the stream has been reached.
*/
@Override
public int read() throws IOException {
return Streams.readSingleByte(this);
}