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

📄 multipartstream.java

📁 this is source code for online album
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * MultipartStream.java
 *
 * Created on 2004年12月28日, 上午12:24
 * 这是一个用于上传文件的底层处理类。
 *
 */


package com.mg.admin;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;


/**
 * 这是一个用于上传文件的底层处理类。
 *
 * <p>使用方法如下:<p>
 * <pre>
 *    try {
 *        MultipartStream multipartStream = new MultipartStream(input,
 *                                                              boundary);
 *        boolean nextPart = malitPartStream.skipPreamble();
 *        OutputStream output;
 *        while(nextPart) {
 *            // 处理头部
 *             header = chunks.readHeader();
 *            // 读取正文
 *            multipartStream.readBodyPart(output);
 *            nextPart = multipartStream.readBoundary();
 *        }
 *    } catch(MultipartStream.MalformedStreamException e) {
 *          // 数据不符合定义
 *    } catch(IOException) {
 *          // 读写错误
 *    }
 *
 * </pre>
 */
public class MultipartStream {
    
    // ----------------------------------------------------- Manifest常量定义
    
    
    /**
     * 在<code>header-part</code>部分定义的最大处理长度
     * (10 kilobytes = 10240 bytes.)。
     */
    public static final int HEADER_PART_SIZE_MAX = 10240;
    
    
    /**
     * 缺省的缓冲大小。
     */
    protected static final int DEFAULT_BUFSIZE = 4096;
    
    
    /**
     * 以字节顺序定义的<code>header-part</code>标志
     * (<code>CRLFCRLF</code>)。
     */
    protected static final byte[] HEADER_SEPARATOR = {0x0D, 0x0A, 0x0D, 0x0A};
    
    
    /**
     * 以字节顺序表示的在包后面用到的定界符(<code>CRLF</code>)。
     */
    protected static final byte[] FIELD_SEPARATOR = { 0x0D, 0x0A };
    
    
    /**
     * 以字节顺序定义的流中的定界符(<code>--</code>)。
     */
    protected static final byte[] STREAM_TERMINATOR = { 0x2D, 0x2D };
    
    
    // ----------------------------------------------------------- 数据成员
    
    
    /**
     * 读取字符的输入流。
     */
    private InputStream input;
    
    
    /**
     * 边界标识的长度。
     */
    private int boundaryLength;
    
    
    /**
     * 要在缓冲中保留的,为了测试定界符的,以字节形式的数据的大小。
     */
    private int keepRegion;
    
    
    /**
     * 边界数组。
     */
    private byte[] boundary;
    
    
    /**
     * 用来处理request请求的缓冲大小。
     */
    private int bufSize;
    
    
    /**
     * 用来处理request请求的缓冲。
     */
    private byte[] buffer;
    
    
    /**
     * 在缓冲中第一个有效的字符索引。
     * <br>
     * 0 <= head < bufSize
     */
    private int head;
    
    
    /**
     * 在buffer + 1缓冲中最后一个有效字符的索引。
     * <br>
     * 0 <= tail <= bufSize
     */
    private int tail;
    
    
    /**
     * 内容的编码方式。
     */
    private String headerEncoding;
    
    
    // ----------------------------------------------------------- Constructors
    
    
    /**
     * 缺省的构造函数。
     *
     * @see #MultipartStream(InputStream, byte[], int)
     * @see #MultipartStream(InputStream, byte[])
     *
     */
    public MultipartStream() {
    }
    
    
    /**
     * 构造函数
     *
     * @param input    输入流
     * @param boundary 边界标识
     * @param bufSize  缓冲大小
     *
     *
     * @see #MultipartStream()
     * @see #MultipartStream(InputStream, byte[])
     *
     */
    public MultipartStream(InputStream input,
            byte[] boundary,
            int bufSize) {
        this.input = input;
        this.bufSize = bufSize;
        this.buffer = new byte[bufSize];
        
        this.boundary = new byte[boundary.length + 4];
        this.boundaryLength = boundary.length + 4;
        this.keepRegion = boundary.length + 3;
        this.boundary[0] = 0x0D;
        this.boundary[1] = 0x0A;
        this.boundary[2] = 0x2D;
        this.boundary[3] = 0x2D;
        System.arraycopy(boundary, 0, this.boundary, 4, boundary.length);
        
        head = 0;
        tail = 0;
    }
    
    
    /**
     * 构造函
     * <p>
     * @param input    输入流
     * @param boundary 边界标识
     *
     *
     * @see #MultipartStream()
     * @see #MultipartStream(InputStream, byte[], int)
     *
     */
    public MultipartStream(InputStream input,
            byte[] boundary)
            throws IOException {
        this(input, boundary, DEFAULT_BUFSIZE);
    }
    
    
    // --------------------------------------------------------- 公共方法
    
    
    /**
     * 返回头部的编码格式,如果没有指定编码格式,则使用缺省的编码。
     *
     *
     * @return 返回头部的编码格式
     */
    public String getHeaderEncoding() {
        return headerEncoding;
    }
    
    
    /**
     * 设置头部的编码格式,如果没有指定编码格式,则使用缺省的编码
     *
     * @param encoding 要设置的编码格式
     */
    public void setHeaderEncoding(String encoding) {
        headerEncoding = encoding;
    }
    
    
    /**
     * 从缓冲中读取一个字节
     *
     * @return 返回下一个字节
     */
    public byte readByte()
    throws IOException {
        // Buffer使用完了吗 ?
        if (head == tail) {
            head = 0;
            // Refill.
            tail = input.read(buffer, head, bufSize);
            if (tail == -1) {
                // 没有更多的数据了
                throw new IOException("No more data is available");
            }
        }
        return buffer[head++];
    }
    
    
    /**
     * 跳过边界标识,是否有更多的<code>encapsulations</code>包含在缓冲中。
     *
     * @return 如果在缓冲中还有包就返回<code>true</code>,否则返回false。
     *
     */
    public boolean readBoundary()
    throws MalformedStreamException {
        byte[] marker = new byte[2];
        boolean nextChunk = false;
        
        head += boundaryLength;
        try {
            marker[0] = readByte();
            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>设置边界符
     *
     * @param 设置边界符号
     *
     */
    public void setBoundary(byte[] boundary)
    throws IllegalBoundaryException {
        if (boundary.length != boundaryLength - 4) {
            throw new IllegalBoundaryException(
                    "The length of a boundary token can not be changed");
        }
        System.arraycopy(boundary, 0, this.boundary, 4, boundary.length);
    }
    
    
    /**

⌨️ 快捷键说明

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