czipoutputstream.java

来自「对eclipse gef进行封装,可以生成图形化编辑器」· Java 代码 · 共 536 行 · 第 1/2 页

JAVA
536
字号
		    return;
		}

		if (entry == null) {
		    throw new ZipException("no current ZIP entry");
		}
		switch (entry.method) {
		case DEFLATED:
		    super.write(b, off, len);
		    break;
		case STORED:
		    written += len;
		    if (written - locoff > entry.size) {
			throw new ZipException(
			    "attempt to write past end of STORED entry");
		    }
		    out.write(b, off, len);
		    break;
		default:
		    throw new InternalError("invalid compression method");
		}
		crc.update(b, off, len);
	    }

	    /**
	     * Finishes writing the contents of the ZIP 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 ZIP file error has occurred
	     * @exception IOException if an I/O exception has occurred
	     */
	    public void finish() throws IOException {
		ensureOpen();
		if (finished) {
		    return;
		}
		if (entry != null) {
		    closeEntry();
		}
		if (entries.size() < 1) {
		    throw new ZipException("ZIP file must have at least one entry");
		}
		// write central directory
		long off = written;
		Enumeration e = entries.elements();
		while (e.hasMoreElements()) {
		    writeCEN((CZipEntry)e.nextElement());
		}
		writeEND(off, written - off);
		finished = true;
	    }

	    /**
	     * Closes the ZIP output stream as well as the stream being filtered.
	     * @exception ZipException if a ZIP file error has occurred
	     * @exception IOException if an I/O error has occurred
	     */
	    public void close() throws IOException {
	        if (!closed) {
	            super.close();
	            closed = true;
	        }
	    }

	    
	    private byte[] getEncodingBytes(String name){
	    	byte[] nameBytes = null; 
			try 
			{ 
			if (this.encoding.toUpperCase().equals("UTF-8")) 
				nameBytes =getUTF8Bytes(name); 
			else 
				nameBytes= name.getBytes(this.encoding); 
			} 
			catch(Exception byteE) 
			{ 
				nameBytes=getUTF8Bytes(name); 
			} 
			return nameBytes;
	    }
	    /*
	     * Writes local file (LOC) header for specified entry.
	     */
	    private void writeLOC(CZipEntry e) throws IOException {
		writeInt(LOCSIG);	    // LOC header signature
		writeShort(e.version);      // version needed to extract
		writeShort(e.flag);         // general purpose bit flag
		writeShort(e.method);       // compression method
		writeInt(e.time);           // last modification time
		if ((e.flag & 8) == 8) {
		    // store size, uncompressed size, and crc-32 in data descriptor
		    // immediately following compressed entry data
		    writeInt(0);
		    writeInt(0);
		    writeInt(0);
		} else {
		    writeInt(e.crc);        // crc-32
		    writeInt(e.csize);      // compressed size
		    writeInt(e.size);       // uncompressed size
		}
		byte[] nameBytes = getEncodingBytes(e.name);		
		writeShort(nameBytes.length);
		writeShort(e.extra != null ? e.extra.length : 0);
		writeBytes(nameBytes, 0, nameBytes.length);
		if (e.extra != null) {
		    writeBytes(e.extra, 0, e.extra.length);
		}
		locoff = written;
	    }

	    /*
	     * Writes extra data descriptor (EXT) for specified entry.
	     */
	    private void writeEXT(CZipEntry e) throws IOException {
		writeInt(EXTSIG);	    // EXT header signature
		writeInt(e.crc);	    // crc-32
		writeInt(e.csize);	    // compressed size
		writeInt(e.size);	    // uncompressed size
	    }

	    /*
	     * Write central directory (CEN) header for specified entry.
	     * REMIND: add support for file attributes
	     */
	    private void writeCEN(CZipEntry e) throws IOException {
		writeInt(CENSIG);	    // CEN header signature
		writeShort(e.version);	    // version made by
		writeShort(e.version);	    // version needed to extract
		writeShort(e.flag);	    // general purpose bit flag
		writeShort(e.method);	    // compression method
		writeInt(e.time);	    // last modification time
		writeInt(e.crc);	    // crc-32
		writeInt(e.csize);	    // compressed size
		writeInt(e.size);	    // uncompressed size
		
		byte[] nameBytes = getEncodingBytes(e.name); 		
		writeShort(nameBytes.length);
		writeShort(e.extra != null ? e.extra.length : 0);
		byte[] commentBytes;
		if (e.comment != null) {
		    commentBytes = getUTF8Bytes(e.comment);
		    writeShort(commentBytes.length);
		} else {
		    commentBytes = null;
		    writeShort(0);
		}
		writeShort(0);		    // starting disk number
		writeShort(0);		    // internal file attributes (unused)
		writeInt(0);		    // external file attributes (unused)
		writeInt(e.offset);	    // relative offset of local header
		writeBytes(nameBytes, 0, nameBytes.length);
		if (e.extra != null) {
		    writeBytes(e.extra, 0, e.extra.length);
		}
		if (commentBytes != null) {
		    writeBytes(commentBytes, 0, commentBytes.length);
		}
	    }

	    /*
	     * Writes end of central directory (END) header.
	     */
	    private void writeEND(long off, long len) throws IOException {
		writeInt(ENDSIG);	    // END record signature
		writeShort(0);		    // number of this disk
		writeShort(0);		    // central directory start disk
		writeShort(entries.size()); // number of directory entries on disk
		writeShort(entries.size()); // total number of directory entries
		writeInt(len);		    // length of central directory
		writeInt(off);		    // offset of central directory
		if (comment != null) {	    // zip file comment
		    byte[] b = getUTF8Bytes(comment);
		    writeShort(b.length);
		    writeBytes(b, 0, b.length);
		} else {
		    writeShort(0);
		}
	    }

	    /*
	     * Writes a 16-bit short to the output stream in little-endian byte order.
	     */
	    private void writeShort(int v) throws IOException {
		OutputStream out = this.out;
		out.write((v >>> 0) & 0xff);
		out.write((v >>> 8) & 0xff);
		written += 2;
	    }

	    /*
	     * Writes a 32-bit int to the output stream in little-endian byte order.
	     */
	    private void writeInt(long v) throws IOException {
		OutputStream out = this.out;
		out.write((int)((v >>>  0) & 0xff));
		out.write((int)((v >>>  8) & 0xff));
		out.write((int)((v >>> 16) & 0xff));
		out.write((int)((v >>> 24) & 0xff));
		written += 4;
	    }

	    /*
	     * Writes an array of bytes to the output stream.
	     */
	    private void writeBytes(byte[] b, int off, int len) throws IOException {
		super.out.write(b, off, len);
		written += len;
	    }

	    /*
	     * Returns the length of String's UTF8 encoding.
	     */
	    static int getUTF8Length(String s) {
	        int count = 0;
	        for (int i = 0; i < s.length(); i++) {
	            char ch = s.charAt(i); 
	            if (ch <= 0x7f) {
	                count++;
	            } else if (ch <= 0x7ff) {
	                count += 2;
	            } else {
	                count += 3;
	            }
	        }
	        return count;
	    }

	    /*
	     * Returns an array of bytes representing the UTF8 encoding
	     * of the specified String.
	     */
	    private static byte[] getUTF8Bytes(String s) {
		char[] c = s.toCharArray();
		int len = c.length;
		// Count the number of encoded bytes...
		int count = 0;
		for (int i = 0; i < len; i++) {
		    int ch = c[i];
		    if (ch <= 0x7f) {
			count++;
		    } else if (ch <= 0x7ff) {
			count += 2;
		    } else {
			count += 3;
		    }
		}
		// Now return the encoded bytes...
		byte[] b = new byte[count];
		int off = 0;
		for (int i = 0; i < len; i++) {
		    int ch = c[i];
		    if (ch <= 0x7f) {
			b[off++] = (byte)ch;
		    } else if (ch <= 0x7ff) {
			b[off++] = (byte)((ch >> 6) | 0xc0);
			b[off++] = (byte)((ch & 0x3f) | 0x80);
		    } else {
			b[off++] = (byte)((ch >> 12) | 0xe0);
			b[off++] = (byte)(((ch >> 6) & 0x3f) | 0x80);
			b[off++] = (byte)((ch & 0x3f) | 0x80);
		    }
		}
		return b;
	    }
	
	
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?