?? compressionresponsestream.java
字號:
package compressionFilters;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
public class CompressionResponseStream extends ServletOutputStream {
protected int compressionThreshold = 0; //是否啟用壓縮的臨界值
protected byte[] buffer = null; //臨時容納寫入的數據的緩沖區
protected int bufferCount = 0; //緩沖區中實際寫如的數據量
protected GZIPOutputStream gzipstream = null;
protected boolean closed = false; //當前流對象是否處于關閉狀態
protected int length = -1;
protected HttpServletResponse response = null;
protected ServletOutputStream output = null;
public CompressionResponseStream(HttpServletResponse response)
throws IOException {
super();
closed = false;
this.response = response;
this.output = response.getOutputStream();
}
//設置是否啟用壓縮的臨界值
protected void setBuffer(int threshold) {
compressionThreshold = threshold;
buffer = new byte[compressionThreshold];
}
public void close() throws IOException {
if (closed)
throw new IOException(
"This output stream has already been closed");
/* 根據gzipstream是否為null,就可以知道寫入的內容是否達到了
* 啟用壓縮的臨界值,因為達到臨界值時,write方法會自動創建
* gzipstream實例對象。
*/
if (gzipstream != null) {
flushToGZip();
gzipstream.close();
gzipstream = null;
} else {
if (bufferCount > 0) {
output.write(buffer, 0, bufferCount);
bufferCount = 0;
}
}
/* 筆者認為這句代碼有些問題,如果啟用了壓縮,在關閉gzipstream流時,
* 底層的output流應該自動關閉,所以,
* 應該將下句代碼放進上面的else從語中
*/
output.close();
closed = true;
}
public void flush() throws IOException {
if (closed) {
throw new IOException("Cannot flush a closed output stream");
}
if (gzipstream != null) {
gzipstream.flush();
}
}
//將buffer緩沖區中的數據寫入到gzipstream對象中
public void flushToGZip() throws IOException {
if (bufferCount > 0) {
writeToGZip(buffer, 0, bufferCount);
bufferCount = 0;
}
}
public void write(int b) throws IOException {
if (closed)
throw new IOException("Cannot write to a closed output stream");
/* 當已經寫入的數據達到了啟用壓縮的臨界值時,
* 則先將buffer緩沖區中的數據寫入到gzipstream對象中
*/
if (bufferCount >= buffer.length) {
flushToGZip();
}
buffer[bufferCount++] = (byte) b;
}
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
if (closed)
throw new IOException("Cannot write to a closed output stream");
if (len == 0)
return;
/* 如果buffer緩沖區中剩余的空間能夠容納要寫入的數據,
* 則先將這些數據寫入到buffer緩沖區中
*/
if (len <= (buffer.length - bufferCount)) {
System.arraycopy(b, off, buffer, bufferCount, len);
bufferCount += len;
return;
}
/* 如果buffer緩沖區中剩余的空間不能夠容納要寫入的數據,
* 則先將buffer緩沖區中原有的數據寫入到gzipstream對象中
*/
flushToGZip();
/* 騰空buffer緩沖區中原有的數據后,判斷整個buffer緩沖區是否能夠
* 容納要寫入的數據,如果能,將這些數據寫入到buffer緩沖區中
*/
if (len <= (buffer.length - bufferCount)) {
System.arraycopy(b, off, buffer, bufferCount, len);
bufferCount += len;
return;
}
/* 如果整個buffer緩沖區的空間都不能夠容納要寫入的數據,
* 則直接將這些數據寫入到gzipstream對象中
*/
writeToGZip(b, off, len);
}
/* 向gzipstream對象中寫入數據,如果是第一次寫入,
* 則還需要首先創建出gzipstream實例對象*/
public void writeToGZip(byte b[], int off, int len) throws IOException {
if (gzipstream == null) {
response.addHeader("Content-Encoding", "gzip");
gzipstream = new GZIPOutputStream(output);
}
gzipstream.write(b, off, len);
}
/* ServletOutputStream類與OutputStream類中都沒有定義closed這個方法,
* 不知這里為何實現這一個方法,筆者看來純屬多余 */
public boolean closed() {
return (this.closed);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -