⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 partialbufferedoutputstream2.java

📁 电子地图服务器,搭建自己的地图服务
💻 JAVA
字号:
/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
 * This code is licensed under the GPL 2.0 license, availible at the root
 * application directory.
 */
package org.vfny.geoserver.util;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;


/**
 * <b>PartialBufferedOutputStream</b><br> Oct 19, 2005<br>
 * <b>Purpose:</b><br>
 * I have modelled this class after the BufferedOutputStream. Several methods
 * are synchronized as a result. The interior of this class uses a
 * ByteArrayOutputStream when it starts and then a BufferedOutputStream. This
 * is essentially a decorator. This class uses a temporary to-memory
 * OutputStream for initial bufferring. This OutputStream is a
 * ByteArrayOutputStream. Once a pre-defined BUFFER_SIZE has been reached, the
 * output that is stored in the ByteArrayOutputStream is output to the real
 * OutputStream to the response. Further data is then written to that response
 * OutputStream. For the first run of this, we will write to memory for the
 * buffered part. Writing to disk is another option. NOTE: If we switch to
 * writing out to disk, we will have to clean up our temporary files with
 * abort(). WARNING: IF you abuse the size of the buffer, you may leak memory
 * if this OutputStream is not terminated. The ByteArrayOutputStream will hold
 * onto its allocated memory even after you call reset() on it. So if you put
 * in 60MB of buffer space, it will stay there until the object is no longer
 * referenced and the garbage collector decides to pick it up. A solution to
 * this would be to use a FileOutputStream instead of the
 * ByteArrayOutputStream. CONTRACT: -close() will NOT flush remaining bytes to
 * the output stream, as per the contract with OutputStream. Close will remove
 * any references to OutputStreams and its HttpServletResponse. -fush() will
 * NOT flush if the buffer is not full. -abort() will succeed if the buffer is
 * not full yet. If the buffer has been filled and the information has been
 * written out to response's OutputStream, the abort reports as having failed.
 * The point of this PartialBufferedOutputStream is to allow an abort before
 * the information has been written out to the real OutputStream. When abort
 * is called the references to any OutputStreams and the HttpServletResponse
 * are removed.
 *
 * @author Brent Owens (The Open Planning Project)
 * @version
 */
public class PartialBufferedOutputStream2 extends OutputStream {
    public static final int DEFAULT_BUFFER_SIZE = 50;

    /** the number of bytes in a kilobyte */
    private final int KILOBYTE = 1024;

    /** Buffer size for the temporary output stream */
    private int BUFFER_SIZE = KILOBYTE;

    /** Temporary output stream, the buffered one */
    private ByteArrayOutputStream out_buffer;

    /**
     * Response output stream, the non-buffered one, this is passed in
     * by the response
     */
    private OutputStream out_real;
    private OutputStream currentStream;

    /**
     * This contains the OutputStream that will be put in out_real when
     * the buffer is full
     */
    private HttpServletResponse response;

    /** Set to true when close() is called to prevent further writing */
    private boolean closed = false;

    /**
             * Constructor Defaults buffer size to 50KB
             * @param response
             */
    public PartialBufferedOutputStream2(HttpServletResponse response)
        throws IOException {
        this(response, DEFAULT_BUFFER_SIZE); // default to 50KB
    }

    /**
             * @param response the response with its output stream to write to once the buffer is full
             * @param kilobytes size, in kilobytes, of the buffer
             */
    public PartialBufferedOutputStream2(HttpServletResponse response, int kilobytes)
        throws IOException {
        if (kilobytes < 1) {
            throw new IllegalArgumentException("Buffer size not greater than 0: " + kilobytes);
        }

        BUFFER_SIZE = KILOBYTE * kilobytes;
        this.response = response;
        out_buffer = new ByteArrayOutputStream(BUFFER_SIZE);
        this.response = response;
        currentStream = out_buffer;
    }

    /**
     * <b>bufferCapacity</b><br><br>
     * <b>Description:</b><br>
     * This will return the max capacity of the buffer in kilobytes.
     *
     * @return the capacity of the buffer in kilobytes
     */
    public int bufferCapacity() {
        return BUFFER_SIZE / KILOBYTE;
    }

    /**
     * <b>bufferSize</b><br><br>
     * <b>Description:</b><br>
     * This will return the size of the buffer, in bytes.
     *
     * @return the size of the buffer in bytes
     */
    public int bufferSize() {
        return out_buffer.size();
    }

    /* (non-Javadoc)
     * @see java.io.OutputStream#write(int)
     *
     * Remember that b is treated as a byte, the 8 low-order bits are read,
     * and the 24 remaining high-order bits of b are ignored.
     */
    public synchronized void write(int b) throws IOException {
        if (closed) {
            return;
        }

        checkBuffer(1);
        currentStream.write(b);
    }

    public void write(byte[] b) throws IOException {
        if (closed) {
            return;
        }

        checkBuffer(b.length);
        currentStream.write(b);
    }

    public void write(byte[] b, int off, int len) throws IOException {
        if (closed) {
            return;
        }

        checkBuffer(len);
        currentStream.write(b, off, len);
    }

    private void checkBuffer(int extraBytes) throws IOException {
        if ((currentStream == out_buffer) && ((out_buffer.size() + extraBytes) >= BUFFER_SIZE)) {
            flushBuffer();
        }
    }

    private void flushBuffer() throws IOException {
        out_real = response.getOutputStream();
        out_buffer.writeTo(out_real);
        out_buffer.reset();
        currentStream = out_real;
    }

    /* (non-Javadoc)
     * @see java.io.OutputStream#flush()
     *
     * If the buffer is not maxed yet, don't flush. If a flush is really really needed,
     * call forceFlush().
     */
    public synchronized void flush() throws IOException {
        if (closed) {
            return;
        }

        if (currentStream == out_buffer) {
            flushBuffer();
        }

        currentStream.flush();
    }

    /* (non-Javadoc)
     * @see java.io.OutputStream#close()
     */
    public void close() throws IOException {
        if (closed) {
            return;
        }

        closed = true;

        // It is not in the contract of close, for OutputStream, to call flush(), 
        //  so I am dyking it out.
        /*
           try {
                   flush();
           }
           catch (IOException ignored) {
           }
         */
        out_buffer.close();
        out_buffer = null;
        out_real = null; // get rid of our local pointer
        response = null; // get rid of our local pointer
                         //if (out_real != null)	// removed so the user has to close their stream
                         //	out_real.close();
    }

    /**
     * <b>abort</b><br><br>
     * <b>Description:</b><br>
     * Abort is called when something bad has happened and we want to get out
     * of writing out to the real stream. This is why we have a buffer. Abort
     * will succeed if the buffer is not full yet. If that is true, then the
     * buffer is cleared and closed. It does NOT close the response's
     * OutputStream
     *
     * @return DOCUMENT ME!
     *
     * @throws IOException
     */
    public boolean abort() throws IOException {
        if ((out_buffer != null) && (out_buffer.size() < BUFFER_SIZE)) {
            out_buffer.close();
            out_buffer = null;
            out_real = null; // get rid of our local pointer
            response = null; // get rid of our local pointer

            return true; // success
        }

        out_real = null; // get rid of our local pointer
        response = null; // get rid of our local pointer

        return false; // buffer already full, sorry
    }
}

⌨️ 快捷键说明

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