httpinputstream.java
来自「OpenJMS是一个开源的Java Message Service API 1.」· Java 代码 · 共 257 行
JAVA
257 行
/** * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided * that the following conditions are met: * * 1. Redistributions of source code must retain copyright * statements and notices. Redistributions must also contain a * copy of this document. * * 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 name "Exolab" must not be used to endorse or promote * products derived from this Software without prior written * permission of Exoffice Technologies. For written permission, * please contact info@exolab.org. * * 4. Products derived from this Software may not be called "Exolab" * nor may "Exolab" appear in their names without prior written * permission of Exoffice Technologies. Exolab is a registered * trademark of Exoffice Technologies. * * 5. Due credit should be given to the Exolab Project * (http://www.exolab.org/). * * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS * ``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 * EXOFFICE TECHNOLOGIES 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. * * Copyright 2004-2005 (C) Exoffice Technologies Inc. All Rights Reserved. * * $Id: HTTPInputStream.java,v 1.3 2005/04/04 15:08:52 tanderson Exp $ */package org.exolab.jms.net.http;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * Reads and buffers input from an {@link java.net.URLConnection}. * * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> * @version $Revision: 1.3 $ $Date: 2005/04/04 15:08:52 $ */class HTTPInputStream extends InputStream { /** * The connection identifier. */ private final String _id; /** * The tunnel servlet URL. */ private final URL _url; /** * The connection information. */ private final HTTPRequestInfo _info; /** * The input stream from the servlet. */ private InputStream _in; /** * The local data buffer. */ private byte[] _data = new byte[1024]; /** * Temporary buffer for single byte reads. */ private final byte[] _byte = new byte[1]; /** * The index into <code>_data</code> where data starts. */ private int _index = 0; /** * The number of available bytes in <code>_data</code>. */ private int _available = 0; /** * The logger. */ private static final Log _log = LogFactory.getLog(HTTPInputStream.class); /** * Construct a new <code>HTTPInputStream</code>. * * @param id the connection identifier * @param url the URL to connect to * @param info the connection information */ public HTTPInputStream(String id, URL url, HTTPRequestInfo info) { _id = id; _url = url; _info = info; } /** * Reads the next byte of data from the input stream. The value byte is * returned as an <code>int</code> in the range <code>0</code> to * <code>255</code>. If no byte is available because the end of the stream * has been reached, the value <code>-1</code> is returned. This method * blocks until input data is available, the end of the stream is detected, * or an exception is thrown. * <p/> * <p> A subclass must provide an implementation of this method. * * @return the next byte of data, or <code>-1</code> if the end of the * stream is reached. * @throws IOException if an I/O error occurs. */ public int read() throws IOException { final int mask = 0xFF; int count = read(_byte, 0, 1); return (count == 1) ? _byte[0] & mask : -1; } /** * Reads up to <code>length</code> bytes of data from the input stream into * an array of bytes. An attempt is made to read as many as * <code>length</code> bytes, but a smaller number may be read, possibly * zero. The number of bytes actually read is returned as an integer. * <p/> * <p> If the first byte cannot be read for any reason other than end of * file, then an <code>IOException</code> is thrown. In particular, an * <code>IOException</code> is thrown if the input stream has been closed. * * @param buffer the buffer into which the data is read * @param offset the start offset in array <code>buffer</code> at which the * data is written * @param length the maximum number of bytes to read * @return the total number of bytes read into the buffer, or * <code>-1</code> if there is no more data because the end of the * stream has been reached. * @throws IOException if an I/O error occurs. * @throws IndexOutOfBoundsException if <code>offset</code> is negative, or * <code>length</code> is negative, or * <code>offset+length</code> is greater * than the length of the array * @throws NullPointerException if <code>buffer</code> is null */ public int read(byte[] buffer, int offset, int length) throws IOException { int count = 0; if (offset < 0 || length < 0) { throw new IndexOutOfBoundsException(); } if (length > 0) { if (_available == 0) { try { doRead(); } catch (IOException exception) { _log.debug(exception, exception); throw exception; } } count = (length <= _available) ? length : _available; if (_log.isDebugEnabled()) { _log.debug("read(length=" + length + "), [id=" + _id + ", available=" + _available + "]"); } if (count > 0) { // copy the available data into the buffer System.arraycopy(_data, _index, buffer, offset, count); _index += count; _available -= count; } } return count; } /** * Read from the connection and cache locally. * * @return the total number of bytes read into the buffer, or * <code>-1</code> if there is no more data because the end of the * stream has been reached. * @throws IOException if the read fails */ protected int doRead() throws IOException { int count = 0; boolean done = false; while (!done) { if (_in == null) { connect(); done = true; } count = _in.read(_data); if (count != -1) { _available = count; _index = 0; done = true; } else { _in.close(); _in = null; } } return count; } /** * Connect to the tunnel servlet and get the input stream. * * @throws IOException for any I/O error */ private void connect() throws IOException { int length = 0; HttpURLConnection connection = null; while (length == 0) { // poll the servlet until data is available, or an error // occurs connection = TunnelHelper.connect(_url, _id, "read", _info); length = connection.getContentLength(); if (length == -1) { // throw new IOException("Content length not specified"); // NOTE: above is commented out as it appears that the content // length may not always be set } else if (length == 0) { try { // delay Thread.sleep(1000); } catch (InterruptedException ignore) { } } } _in = connection.getInputStream(); if (_log.isDebugEnabled()) { _log.debug("connect(), [id=" + _id + ", contentLength=" + length + "]"); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?