📄 bufferedservletoutputstream.java
字号:
/* * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Attic/BufferedServletOutputStream.java,v 1.14.2.2 2000/11/10 06:42:48 craigmcc Exp $ * $Revision: 1.14.2.2 $ * $Date: 2000/11/10 06:42:48 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.tomcat.core;import org.apache.tomcat.util.StringManager;import java.io.*;import javax.servlet.ServletOutputStream;/* Was: server.ServletOutputStreamImpl. - replaced private with protected - removed OutputStram out - replaced ServerResponse with Response - replaced out.write() with abstract doWrite that will be implemented by protocols - replaced out.close() with abstract endResponse() - response.writeHeaders() take no parameters ( response knows where to write anyway ) - replaced response.sendHeaders with abstract sendHeaders( response ) *//** * * Works only if you extend ResponseImpl and override doWrite() - * all other implementations of Response should provide their own Stream * * @author James Duncan Davidson [duncan@eng.sun.com] * @author Jason Hunter [jch@eng.sun.com] * @author James Todd [gonzo@eng.sun.com] * @author Mandar Raje [mandar@eng.sun.com] */public class BufferedServletOutputStream extends ServletOutputStream { protected static StringManager sm = StringManager.getManager(Constants.Package); protected boolean usingWriter = false; // XXX // need to make buffer a configurable property protected static final int DEFAULT_BUFFER_SIZE = 8*1024; protected byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; protected int bufferSize = DEFAULT_BUFFER_SIZE; protected int bufferCount = 0; protected int totalCount = 0; protected boolean closed = false; ResponseImpl resA; protected BufferedServletOutputStream() { // System.out.println("new BOS " + closed); } protected BufferedServletOutputStream(Response resA) { // System.out.println("new BOS " + closed); setResponse(resA); }// public void setResponseAdapter( Response resA ) {// this.resA=resA;// } protected void doWrite( byte buffer[], int pos, int count) throws IOException { resA.doWrite( buffer, pos, count); } protected void sendHeaders() throws IOException { if(resA!=null) resA.endHeaders(); } public void setResponse( Response response ) { this.resA=(ResponseImpl)response; } // Hack for the buffering issue. public void setUsingWriter(boolean uwrt) { this.usingWriter = uwrt; } // XXX // write all the other write methods here so that we dont // have this 1 byte bottleneck here. public void write(int i) throws IOException { if (closed) { // System.out.println("CLOSED"); return; } // System.out.print("."); buffer[bufferCount] = (byte)i; bufferCount++; totalCount++; if (bufferCount >= buffer.length) { reallyFlush(); } } 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) { return; } if (len < 0) { String msg = sm.getString("servletOutputStreamImpl.write.iae"); throw new IllegalArgumentException(msg); } // If the whole thing fits in the buffer, then just put it there. if (len < (buffer.length - bufferCount)) { System.arraycopy(b, off, buffer, bufferCount, len); bufferCount += len; totalCount += len; } else { // Otherwise, we might as well flush and then write out full // buffers of data directly to the underlying stream. Whatever // is left over, we simply put in the buffer. // This code was adapted (and cleaned up) from Aaron Renn's // BufferedOutputStream implementation from the Classpath project. reallyFlush(); int iters = len / buffer.length; int leftoverStart = iters * buffer.length; int leftoverLen = len - leftoverStart; for (int i = 0; i < iters; i++) doWrite(b, off + (i * buffer.length), buffer.length); totalCount += leftoverStart; if ((len % buffer.length) != 0) { System.arraycopy(b, off + leftoverStart, buffer, bufferCount, leftoverLen); bufferCount += leftoverLen; totalCount += leftoverLen; } } } public void print(String s) throws IOException { if (s==null) s="null"; int len = s.length(); for (int i = 0; i < len; i++) { char c = s.charAt (i); // // XXX NOTE: This is clearly incorrect for many strings, // but is the only consistent approach within the current // servlet framework. It must suffice until servlet output // streams properly encode their output. // if ((c & 0xff00) != 0) { // high order byte must be zero String errMsg = sm.getString( "servletOutputStreamImpl.fmt.not_iso8859_1", new Object[] {new Character(c)}); throw new IOException(errMsg); } write(c); } } // If a servlet is using PrintWriter then this method is NO-OP. public void flush() throws IOException { if (this.usingWriter == false) reallyFlush(); } public void reallyFlush() throws IOException { try { if (!resA.isBufferCommitted()) { sendHeaders(); resA.setBufferCommitted(true); } if (bufferCount > 0) { // out.write(buffer, 0, bufferCount); Request req=resA.getRequest(); ContextManager cm=req.getContextManager(); cm.doBeforeCommit( req, resA ); doWrite( buffer, 0, bufferCount ); } } finally { bufferCount = 0; } } public void close() throws IOException { reallyFlush(); closed = true; // out.close(); } public boolean isContentWritten() { return totalCount > 0 ? true : false; }// public boolean isCommitted() {// return res.isCommited();// } public int getBufferSize() { return buffer.length; } public void setBufferSize(int size) throws IllegalStateException { // If requested size is less than current, this is a no-op. if (size <= bufferSize) { return; } // Make sure size is evenly divisible by 8K // This helps our buffer align with the PrintWriter buffer int eightK = 8*1024; if (size % eightK != 0) { size = ((size / eightK) + 1) * eightK; // round up } // Allocate buffer of the requested size. bufferSize = size; buffer = new byte[size]; } public void reset() throws IllegalStateException { // If buffer is already commited, throw IllegalStateException. if (resA.isBufferCommitted()) { String msg = sm.getString("servletOutputStreamImpl.reset.ise"); throw new IllegalStateException(msg); } // Reset the buffer. bufferCount = 0; totalCount = 0; // System.out.println("Reset buffer "); } /** Reuse the object instance, avoid GC */ public void recycle() { // System.out.println("Recycle BOS " ); bufferCount = 0; totalCount = 0; closed = false; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -