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

📄 multipartstream.java

📁 apache commons-fileupload-1.2.jar
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        tail = 0;    }    /**     * <p> Constructs a <code>MultipartStream</code> with a default size buffer.     *     * @param input    The <code>InputStream</code> to serve as a data source.     * @param boundary The token used for dividing the stream into     *                 <code>encapsulations</code>.     * @param pNotifier An object for calling the progress listener, if any.     *     *     * @see #MultipartStream(InputStream, byte[], int, ProgressNotifier)     */    MultipartStream(InputStream input,            byte[] boundary,            ProgressNotifier pNotifier) {        this(input, boundary, DEFAULT_BUFSIZE, pNotifier);    }    /**     * <p> Constructs a <code>MultipartStream</code> with a default size buffer.     *     * @param input    The <code>InputStream</code> to serve as a data source.     * @param boundary The token used for dividing the stream into     *                 <code>encapsulations</code>.     *     * @deprecated Use {@link #MultipartStream(InputStream, byte[],     *  ProgressNotifier)}.     * @see #MultipartStream(InputStream, byte[], int, ProgressNotifier)     */    public MultipartStream(InputStream input,            byte[] boundary) {        this(input, boundary, DEFAULT_BUFSIZE, null);    }    // --------------------------------------------------------- Public methods    /**     * Retrieves the character encoding used when reading the headers of an     * individual part. When not specified, or <code>null</code>, the platform     * default encoding is used.     *     * @return The encoding used to read part headers.     */    public String getHeaderEncoding() {        return headerEncoding;    }    /**     * Specifies the character encoding to be used when reading the headers of     * individual parts. When not specified, or <code>null</code>, the platform     * default encoding is used.     *     * @param encoding The encoding used to read part headers.     */    public void setHeaderEncoding(String encoding) {        headerEncoding = encoding;    }    /**     * Reads a byte from the <code>buffer</code>, and refills it as     * necessary.     *     * @return The next byte from the input stream.     *     * @throws IOException if there is no more data available.     */    public byte readByte()    throws IOException {        // Buffer depleted ?        if (head == tail) {            head = 0;            // Refill.            tail = input.read(buffer, head, bufSize);            if (tail == -1) {                // No more data available.                throw new IOException("No more data is available");            }            notifier.noteBytesRead(tail);        }        return buffer[head++];    }    /**     * Skips a <code>boundary</code> token, and checks whether more     * <code>encapsulations</code> are contained in the stream.     *     * @return <code>true</code> if there are more encapsulations in     *         this stream; <code>false</code> otherwise.     *     * @throws MalformedStreamException if the stream ends unexpecetedly or     *                                  fails to follow required syntax.     */    public boolean readBoundary()            throws MalformedStreamException {        byte[] marker = new byte[2];        boolean nextChunk = false;        head += boundaryLength;        try {            marker[0] = readByte();            if (marker[0] == LF) {                // Work around IE5 Mac bug with input type=image.                // Because the boundary delimiter, not including the trailing                // CRLF, must not appear within any file (RFC 2046, section                // 5.1.1), we know the missing CR is due to a buggy browser                // rather than a file containing something similar to a                // boundary.                return true;            }            marker[1] = readByte();            if (arrayequals(marker, STREAM_TERMINATOR, 2)) {                nextChunk = false;            } else if (arrayequals(marker, FIELD_SEPARATOR, 2)) {                nextChunk = true;            } else {                throw new MalformedStreamException(                "Unexpected characters follow a boundary");            }        } catch (IOException e) {            throw new MalformedStreamException("Stream ended unexpectedly");        }        return nextChunk;    }    /**     * <p>Changes the boundary token used for partitioning the stream.     *     * <p>This method allows single pass processing of nested multipart     * streams.     *     * <p>The boundary token of the nested stream is <code>required</code>     * to be of the same length as the boundary token in parent stream.     *     * <p>Restoring the parent stream boundary token after processing of a     * nested stream is left to the application.     *     * @param boundary The boundary to be used for parsing of the nested     *                 stream.     *     * @throws IllegalBoundaryException if the <code>boundary</code>     *                                  has a different length than the one     *                                  being currently parsed.     */    public void setBoundary(byte[] boundary)            throws IllegalBoundaryException {        if (boundary.length != boundaryLength - BOUNDARY_PREFIX.length) {            throw new IllegalBoundaryException(            "The length of a boundary token can not be changed");        }        System.arraycopy(boundary, 0, this.boundary, BOUNDARY_PREFIX.length,                boundary.length);    }    /**     * <p>Reads the <code>header-part</code> of the current     * <code>encapsulation</code>.     *     * <p>Headers are returned verbatim to the input stream, including the     * trailing <code>CRLF</code> marker. Parsing is left to the     * application.     *     * <p><strong>TODO</strong> allow limiting maximum header size to     * protect against abuse.     *     * @return The <code>header-part</code> of the current encapsulation.     *     * @throws MalformedStreamException if the stream ends unexpecetedly.     */    public String readHeaders()    throws MalformedStreamException {        int i = 0;        byte[] b = new byte[1];        // to support multi-byte characters        ByteArrayOutputStream baos = new ByteArrayOutputStream();        int sizeMax = HEADER_PART_SIZE_MAX;        int size = 0;        while (i < HEADER_SEPARATOR.length) {            try {                b[0] = readByte();            } catch (IOException e) {                throw new MalformedStreamException("Stream ended unexpectedly");            }            size++;            if (b[0] == HEADER_SEPARATOR[i]) {                i++;            } else {                i = 0;            }            if (size <= sizeMax) {                baos.write(b[0]);            }        }        String headers = null;        if (headerEncoding != null) {            try {                headers = baos.toString(headerEncoding);            } catch (UnsupportedEncodingException e) {                // Fall back to platform default if specified encoding is not                // supported.                headers = baos.toString();            }        } else {            headers = baos.toString();        }        return headers;    }    /**     * <p>Reads <code>body-data</code> from the current     * <code>encapsulation</code> and writes its contents into the     * output <code>Stream</code>.     *     * <p>Arbitrary large amounts of data can be processed by this     * method using a constant size buffer. (see {@link     * #MultipartStream(InputStream,byte[],int, ProgressNotifier) constructor}).     *     * @param output The <code>Stream</code> to write data into. May     *               be null, in which case this method is equivalent     *               to {@link #discardBodyData()}.     *     * @return the amount of data written.     *     * @throws MalformedStreamException if the stream ends unexpectedly.     * @throws IOException              if an i/o error occurs.     */    public int readBodyData(OutputStream output)            throws MalformedStreamException, IOException {        final InputStream istream = newInputStream();        return (int) Streams.copy(istream, output, false);    }    /**     * Creates a new {@link ItemInputStream}.     * @return A new instance of {@link ItemInputStream}.     */    ItemInputStream newInputStream() {        return new ItemInputStream();    }    /**     * <p> Reads <code>body-data</code> from the current     * <code>encapsulation</code> and discards it.     *     * <p>Use this method to skip encapsulations you don't need or don't     * understand.     *     * @return The amount of data discarded.     *     * @throws MalformedStreamException if the stream ends unexpectedly.     * @throws IOException              if an i/o error occurs.     */    public int discardBodyData()    throws MalformedStreamException,    IOException {        return readBodyData(null);    }    /**     * Finds the beginning of the first <code>encapsulation</code>.     *     * @return <code>true</code> if an <code>encapsulation</code> was found in     *         the stream.     *     * @throws IOException if an i/o error occurs.     */    public boolean skipPreamble()    throws IOException {        // First delimiter may be not preceeded with a CRLF.        System.arraycopy(boundary, 2, boundary, 0, boundary.length - 2);        boundaryLength = boundary.length - 2;        try {            // Discard all data up to the delimiter.            discardBodyData();            // Read boundary - if succeded, the stream contains an            // encapsulation.            return readBoundary();        } catch (MalformedStreamException e) {            return false;        } finally {            // Restore delimiter.            System.arraycopy(boundary, 0, boundary, 2, boundary.length - 2);            boundaryLength = boundary.length;            boundary[0] = CR;            boundary[1] = LF;        }    }    /**     * Compares <code>count</code> first bytes in the arrays     * <code>a</code> and <code>b</code>.     *     * @param a     The first array to compare.     * @param b     The second array to compare.     * @param count How many bytes should be compared.     *     * @return <code>true</code> if <code>count</code> first bytes in arrays     *         <code>a</code> and <code>b</code> are equal.     */    public static boolean arrayequals(byte[] a,            byte[] b,            int count) {        for (int i = 0; i < count; i++) {            if (a[i] != b[i]) {                return false;            }        }        return true;    }    /**     * Searches for a byte of specified value in the <code>buffer</code>,     * starting at the specified <code>position</code>.     *     * @param value The value to find.     * @param pos   The starting position for searching.     *     * @return The position of byte found, counting from beginning of the     *         <code>buffer</code>, or <code>-1</code> if not found.     */    protected int findByte(byte value,            int pos) {        for (int i = pos; i < tail; i++) {            if (buffer[i] == value) {                return i;            }        }        return -1;    }    /**

⌨️ 快捷键说明

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