nativepackedoutputstream.java
来自「java调用ie浏览器demo源码,可以用在windows或者linux」· Java 代码 · 共 438 行 · 第 1/2 页
JAVA
438 行
public void setLevel(int level) {
this.level = level;
}
/**
* Begins writing a new CAB file entry and positions the stream to the
* start of the entry data. Closes the current entry if still active.
* The default compression method will be used if no compression method
* was specified for the entry, and the current time will be used if
* the entry has no set modification time.
* @param e the ZIP entry to be written
* @exception java.util.zip.ZipException if a ZIP format error has occurred
* @exception IOException if an I/O error has occurred
*/
@Override
public void putNextEntry(ZipEntry e) throws IOException {
checkValid();
if( null!= entry ){
closeEntry(); // close previous entry
}
if( null==e || e.toString().isEmpty() ){
return;
}
String en = e.getName();
if(File.separatorChar!='/'){
en.replace(File.separatorChar, '/');
}
if( names.containsKey(en) ) {
throw new ZipException("duplicate entry: " + en);
}
entry = e;
ZipEntryAccessor.setName(entry, en);
if( -1 == entry.getTime() ){
entry.setTime(System.currentTimeMillis());
}
//re-code DEFLATED const for compatibility reason
int emethod = entry.getMethod();
if( -1==emethod || DEFLATED==emethod ){
setMethod(entry, method); // use default method
}
switch( entry.getMethod() ) {
case METHOD_NONE:
case METHOD_MSZIP:
case METHOD_QUANTUM:
case METHOD_LZX:
case DEFLATED:
break;
default:
throw new ZipException("unsupported compression method");
}
names.put(en, entry);
putNextEntryNative(osNative, entry, level);
}
private static native void putNextEntryNative(long osNative, ZipEntry e, int level);
/**
* Closes the current CAB entry and positions the stream for writing
* the next entry.
* @exception ZipException if a CAB format error has occurred
* @exception IOException if an I/O error has occurred
*/
@Override
public void closeEntry() throws IOException {
if (null != entry && 0 != osNative) {
long newCrc = crc.getValue();
crc.reset();
//Not cheking now due to different packing algorithms.
//Due to "solid" packing algorithm the packed size can be equal to 0 or
//greater than unpacked size.
long newCSize = closeEntryNative( osNative, newCrc );
entry.setCompressedSize(newCSize);
long newSize = actualUncomressedSize;
actualUncomressedSize = 0;
long oldSize = entry.getSize();
entry.setSize(newSize);
long oldCrc = entry.getCrc();
entry.setCrc(newCrc);
entry = null;
if( -1!=oldSize && newSize != oldSize ){
throw new ZipException(
"invalid entry size (expected " + oldSize +
", but got " + newSize + " bytes)");
}
//in 0xffffffffL "L" suffix is VERY critical!
if( (0xffffffffL != (oldCrc & 0xffffffffL)) && (newCrc!=oldCrc) ){
throw new ZipException(
"invalid entry crc-32 (expected 0x" +
Long.toHexString(oldCrc) + ", but got 0x" +
Long.toHexString(newCrc) + ")");
}
}
}
/**
* @param osNative native handler to stream processor
* @param crc Java-calculated CRC
* @return the count of bytes were written to base output stream (compressed size)
*/
private static native long closeEntryNative(long osNative, long crc);
/**
* Callback from native code that reserves space for crc and compressed
* size that are not natively supported in OS DLL.
* @return length-model for final {@link #getEntrySuffix} call
*/
protected String getEntrySuffixStub()
{
//call ones to reserve additional bytes in file name
//for storing extended attribytes
return "{01234567-01234567}";
}
/**
* Callback from native code that stores real crc and compressed size
* values that are not natively supported in OS DLL.
* @param entryName CAB entry name for modification
* @return modified CAB entry name
* @throws java.io.IOException
*/
protected String getEntrySuffix(String entryName) throws IOException
{
ZipEntry ze = names.get(entryName);
if( null == ze){
return null;
}
Formatter f = new Formatter();
f.format("{%08x-%08x}", ze.getCrc(), ze.getCompressedSize());
String ret = f.toString();
if( ret.length() > getEntrySuffixStub().length() ){
throw new ZipException(
"no room for extended attributes (reserved:" +
getEntrySuffixStub() + ", but stored " +
ret + ")");
}
return f.toString();
}
/**
* Writes an array of bytes to the current CAB entry data. This method
* will block until all the bytes are written.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception ZipException if a CAB file error has occurred
* @exception IOException if an I/O error has occurred
*/
@Override
public synchronized void write(byte[] b, int off, int len)
throws IOException
{
checkValid();
if (off < 0 || len < 0 || off > b.length - len) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
if (null == entry) {
throw new ZipException("no current ZIP entry");
}
writeNativeBytes(osNative, b, off, len);
actualUncomressedSize += len;
//System.out.println(actualUncomressedSize);
crc.update(b, off, len);
}
private static native void writeNativeBytes(long osNative, byte[] b, int off, int len) throws IOException;
/**
* Finishes writing the content of the CAB output stream without closing
* the underlying stream. Use this method when applying multiple filters
* in succession to the same output stream.
* @exception ZipException if a CAB file error has occurred
* @exception IOException if an I/O exception has occurred
*/
@Override
public void finish() throws IOException {
checkValid();
if (null != entry) {
closeEntry();
}
finishNative(osNative);
}
private static native void finishNative(long osNative) throws IOException;
/**
* Closes the CAB output stream as well as the stream being filtered.
* @exception ZipException if a CAB file error has occurred
* @exception IOException if an I/O error has occurred
*/
@Override
public void close() throws IOException {
//this call are in super:
// finish();
// if(null != os)
// os.close();
try{
super.close();
} finally {
if(0 != osNative) {
closeNative(osNative);
osNative = 0;
}
}
}
private static native void closeNative(long osNative);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?