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

📄 uploadreader.java

📁 java系统通用框架 很实用的东东 一般人都看的懂,
💻 JAVA
字号:
/*****************************************************************************
* (C) Copyright 2004 。
* 保留对所有使用、复制、修改和发布整个软件和相关文档的权利。
* 本计算机程序受著作权法和国际公约的保护,未经授权擅自复制或
* 传播本程序的全部或部分,可能受到严厉的民事和刑事制裁,并
* 在法律允许的范围内受到最大可能的起诉。
*/

 /*****************************************************************************
  * @作者:Golden Peng
  * @版本: 1.0
  * @时间: 2002-10-08
  */
 /*****************************************************************************
  * 修改记录清单
  * 修改人  :
  * 修改记录:
  * 修改时间:
  * 修改描述:
  *
  */
package com.corp.bisc.ebiz.util;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.corp.bisc.ebiz.exception.*;

/**
 * UploadReader用于处理上传文件的http请求。
 *
 * 在上传文件的http请求中,表单内容(包括上传的文件)是用multipart/form-data
 * 的格式封装的。UploadReader提供方法从multipart/form-data格式中取出客户提
 * 交过来的参数。
 *
 * 下面是一个用于上传文件和参数的表单的例子:
 * <br>
 *&lt;html&gt;&lt;head&gt;&lt;title&gt;Upload Test Form&lt;/title&gt;&lt;/head&gt;<br>
 *&lt;body&gt;<br>
 *&lt;form name = &quot;frmTest&quot; method = &quot;post&quot; action = &quot;/servlet/upload.test&quot;<br>
 *enctype = &quot;multipart/form-data&quot;&gt;<br>
 *&lt;input type = &quot;text&quot; name = &quot;txt1&quot;&gt;&lt;br&gt;<br>
 *&lt;input type = &quot;file&quot; name = &quot;file1&quot;&gt;&lt;br&gt;<br>
 *&lt;input type = &quot;text&quot; name = &quot;txt2&quot;&gt;&lt;br&gt;<br>
 *&lt;input type = &quot;file&quot; name = &quot;file2&quot;&gt;&lt;br&gt;<br>
 *&lt;input type = &quot;submit&quot;&gt;<br>
 *&lt;/form&gt;<br>
 *&lt;/body&gt;<br>
 *&lt;/html&gt;
 *
 * 上传过来的数据划分为多个部分,每个部分包含两段,参数头段和正文段,代表提
 * 交来的表单内的一个参数。
 * 参数头段说明了参数的名称。如果参数是一个上传的文件,则头段内还包含其文件名
 * 以及文件类型。
 * 正文段包含的参数值。如果参数是一个上传的文件,则正文段包含了整个文件。
 * 因此,利用UploadReader提取参数的过程为:
 * 1.调用getHeader()读取参数头段,获得参数名,判断该参数是否为上传的文件
 * 2.如果该参数不是上传的文件,调用getParamValue()从正文段中获取参数值
 * 3.如果该参数是上传的文件,调用getBodyChar()从正文段中读取文件字节,直到
 *   getBodyChar()返回UploadReader.EOF。
 * 4.回到第1步,处理下一个参数。
 *
 * 下面是一个完整的处理文件上传的例子。该例子将http请求带过来的所有参数、文件
 * 名用表格显示出来,并将上传过来的文件保存在c:\temp目录下。http请求中可以包含
 * 任意数目的参数及文件。
 * <code><br>
 * try {<br>
 * int c;<br>
 * MultipartHeader multipartHeader;<br>
 * UploadReader uploadReader = new UploadReader(request);<br>
 * FileOutputStream foStream;
 * <p> response.setContentType(&quot;text/html&quot;);<br>
 *   PrintWriter out = response.getWriter();<br>
 *   out.println(&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;Result of Upload Test&lt;/title&gt;&lt;/head&gt;&quot;);<br>
 *   out.println(&quot;&lt;body&gt;&quot;);<br>
 *   out.println(&quot;&lt;table border=1 width=100%&gt;&quot;);<br>
 *   out.println(&quot;&lt;tr&gt;&lt;th&gt;Type&lt;/th&gt;&lt;th&gt;Name&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;&quot;);</p>
 * <p> while ((multipartHeader = uploadReader.getHeader()) != null) {<br>
 *   out.println(&quot;&lt;tr&gt;&quot;);</p>
 * <p> if (multipartHeader.isFile()) {<br>
 *   out.println(&quot;&lt;td&gt;File&lt;/td&gt;&quot;);<br>
 *   out.println(&quot;&lt;td&gt;&quot; + multipartHeader.getParamName() + &quot;&lt;/td&gt;&quot;);<br>
 *   out.println(&quot;&lt;td&gt;&quot; + multipartHeader.getFileName() + &quot;&lt;/td&gt;&quot;);</p>
 * <p> if (multipartHeader.getFileName().compareTo(&quot;&quot;) != 0) {<br>
 *   //create a local file for saving uploaded file<br>
 *   foStream = <br>
 *   new FileOutputStream(<br>
 *   &quot;c:\\temp&quot;<br>
 *   + multipartHeader.getFileName().substring(<br>
 *   multipartHeader.getFileName().lastIndexOf(&quot;\\&quot;))); <br>
 *   //save uploaded file<br>
 *   while ((c = uploadReader.getBodyChar()) != UploadReader.EOF) {<br>
 *   foStream.write(c);<br>
 *   }<br>
 *   foStream.close();<br>
 *   } else {<br>
 *   uploadReader.skipFile();<br>
 *   }<br>
 *   } else {<br>
 *   out.println(&quot;&lt;td&gt;Param&lt;/td&gt;&quot;);<br>
 *   out.println(&quot;&lt;td&gt;&quot; + multipartHeader.getParamName() + &quot;&lt;/td&gt;&quot;);<br>
 *   out.println(&quot;&lt;td&gt;&quot; + uploadReader.getParamValue() + &quot;&lt;/td&gt;&quot;);<br>
 *   }<br>
 *   out.println(&quot;&lt;/tr&gt;&quot;);<br>
 *   }<br>
 *   out.println(&quot;&lt;/table&gt;&quot;);<br>
 *   out.println(&quot;&lt;/body&gt;&quot;);<br>
 *   out.println(&quot;&lt;/html&gt;&quot;);<br>
 *   out.close();<br>
 *   } catch (Throwable theException) {<br>
 *   System.out.println(theException);<br>
 *   }</p>
 * </code>
 *
 * @author: Jim, Yang Jiang Ming
 */
public class UploadReader {
	class UploadReaderInputStream extends InputStream {
		UploadReader m_reader;

		public UploadReaderInputStream(UploadReader reader) {
			m_reader = reader;
		}

		public int read() throws IOException {
			int c;

			try {
				c = m_reader.getBodyChar();
				if (c < 0) {
					c += 256;
				}
				if (c == UploadReader.EOF) {
					c = -1;
				}

				return c;
			}
			catch(UploadReaderException e) {
				throw new IOException(e.toString());
			}
		}
	}

	//{ constants for buffer status
	protected final static int BUFFER_STATUS_HEADER = 10;
	protected final static int BUFFER_STATUS_BODY = 20;
	protected final static int BUFFER_STATUS_FILE = 30;
	protected final static int BUFFER_STATUS_VALUE = 40;
	protected final static int BUFFER_STATUS_END = 50;
	protected final static int BUFFER_STATUS_ERROR = 60;
	//}

	protected final static int BUFFER_SIZE = 1024000;
	protected final static int BOUNDARY_SIZE = 1024;
	protected final static int SAFE_SIZE = BUFFER_SIZE - BOUNDARY_SIZE;

	public final static int EOF = 255;

	/** input stream */
	protected ServletInputStream m_is;
	/** indicates whether the m_is has came to end */
	protected boolean m_bEndOfIs;
	/** indicate whether the post parameters are sent in multi-part format */
	protected boolean m_bIsMultipart;
	/** boundary for multipart data */
	protected String m_strBoundary;
	/** boundary for multipart data in byte array*/
	protected byte[] m_baBoundary;
	/** buffer for multipart data */
	protected byte[] m_baBuffer;
	/** pointer to next byte to read in buffer */
	protected int m_iPtr;
	/** pointer to last available bye in buffer */
	protected int m_iEndPtr;
	/** buffer status */
	protected int m_iBufferStatus;
	/** temporary byte array */
	protected byte[] m_baTemp = new byte[1024];

	/**
	 * 构造函数
	 * @param request http请求
	 */
	public UploadReader(HttpServletRequest request)
		throws UploadReaderException, IOException {
		super();

		m_bEndOfIs = false;
		m_baBuffer = new byte[BUFFER_SIZE];
		m_iPtr = -1;
		m_iEndPtr = BUFFER_SIZE;

		m_is = request.getInputStream();

		//{is the request data in multipart format?
		if (request.getMethod().equals("POST")
			&& request.getContentType().startsWith("multipart/form-data")) {
			m_bIsMultipart = true;
		} else {
			m_bIsMultipart = false;
		}
		//}

		if (m_bIsMultipart) {
			//{get boundary string
			int index = request.getContentType().indexOf("boundary=");
			if (index < 0) {
				throw new UploadReaderException("Cannot get boundary.");
			}
			m_strBoundary = "--" + request.getContentType().substring(index + 9);
			m_baBoundary = m_strBoundary.getBytes();
			//}

			readInBuffer();
		}
	}
	/**
	 * 从上传的文件中读取一个字节。
	 * @return int 如果为UploadReader.EOF,表示文件已经读完。
	 */
	public int getBodyChar() throws UploadReaderException, IOException {
		int i;

		if (m_iPtr >= SAFE_SIZE)
			readInBuffer();

		if (m_iPtr >= m_iEndPtr)
			throw new UploadReaderException("End of input stream.");

		//must in body
		if (!(m_iBufferStatus == BUFFER_STATUS_VALUE
			|| m_iBufferStatus == BUFFER_STATUS_FILE))
			throw new UploadReaderException("Not in body");

		if (m_baBuffer[m_iPtr] == 0x0d
			&& m_baBuffer[m_iPtr + 1] == 0x0a) { //check if encounter the end of body
			for (i = 0; i < m_baBoundary.length; i++) {
				if (m_baBuffer[m_iPtr + 2 + i] != m_baBoundary[i])
					break;
			}
			if (i == m_baBoundary.length) {
				m_iPtr += 2;
				//change status
				if (m_baBuffer[m_iPtr + m_baBoundary.length] == '-'
					&& m_baBuffer[m_iPtr + m_baBoundary.length + 1] == '-') { //end of buffer
					m_iBufferStatus = BUFFER_STATUS_END;
					m_iPtr += m_baBoundary.length + 2;
				} else {
					m_iBufferStatus = BUFFER_STATUS_HEADER;
				}
				return EOF;
			}
		}

		return m_baBuffer[m_iPtr++];
	}
	public InputStream getBodyInputStream() throws UploadReaderException {
		if (!(m_iBufferStatus == BUFFER_STATUS_VALUE
			|| m_iBufferStatus == BUFFER_STATUS_FILE))
			throw new UploadReaderException("Not in body");
		return new UploadReaderInputStream(this);
	}
	/**
	 * 读取头段。
	 * @return MultipartHeader 头段说明
	 */
	public MultipartHeader getHeader() throws UploadReaderException, IOException {
		int i, j;

		if (m_iBufferStatus == BUFFER_STATUS_END) {
			return null;
		}

		if (m_iBufferStatus != BUFFER_STATUS_HEADER) {
			throw new UploadReaderException("Not in header.");
		}

		MultipartHeader multipartHeader = new MultipartHeader();
		String strTemp = readHeaderLine();

		if (strTemp.compareTo(m_strBoundary) != 0) {
			throw new UploadReaderException("Error in header: expect boundary.");
		}

		strTemp = readHeaderLine();

		//{get param name
		i = strTemp.indexOf("name=");
		j = strTemp.indexOf("\"", i + 6);
		multipartHeader.setParamName(strTemp.substring(i + 6, j));
		//}

		//{get file name and content type when this is a header for a file
		i = strTemp.indexOf("filename=");
		if (i > 0) { //file name exist
			//{get file name
			j = strTemp.indexOf("\"", i + 10);
			multipartHeader.setFileName(strTemp.substring(i + 10, j));
			multipartHeader.setIsFile(true);
			//}

			//{get content type
			strTemp = readHeaderLine();
			if (!strTemp.startsWith("Content-Type: ")) {
				throw new UploadReaderException("No content type.");
			}
			multipartHeader.setContentType(strTemp.substring(14));
			//}
		} else {
			multipartHeader.setIsFile(false);
		}
		//}

		//{skip remaining header lines
		while (m_iBufferStatus == BUFFER_STATUS_HEADER) {
			strTemp = readHeaderLine();
		}
		//}

		if (multipartHeader.isFile()) {
			m_iBufferStatus = BUFFER_STATUS_FILE;
		} else {
			m_iBufferStatus = BUFFER_STATUS_VALUE;
		}

		return multipartHeader;
	}
	/**
	 * 从正文段中读取参数值。
	 * @return java.lang.String 参数值
	 */
	public String getParamValue() throws UploadReaderException, IOException {
		StringBuffer sb = new StringBuffer("");
		byte[] baTemp = new byte[BOUNDARY_SIZE];
		int i, j = 0;

		if (m_iBufferStatus != BUFFER_STATUS_VALUE) //not in value body
			throw new UploadReaderException("Not in value");

		i = getBodyChar();
		while (i != EOF) {
			baTemp[j++] = (byte) i;
			i = getBodyChar();

			if (j == BOUNDARY_SIZE) {
				sb.append(new String(baTemp, 0, j));
				j = 0;
			}
		}

		if (j == 0) {
			return sb.toString();
		}

		return sb.append(new String(baTemp, 0, j)).toString();
	}
	protected boolean isEndOfBuffer() {
		return m_iPtr >= m_iEndPtr;
	}
	/**
	 * 判断请求是否用multipart/form-data的格式传递参数的。
	 * @return boolean
	 */
	public boolean isMultipart() {
		return m_bIsMultipart;
	}
	protected synchronized String readHeaderLine()
		throws UploadReaderException, IOException {
		int i = 0;

		//must in header
		if (m_iBufferStatus != BUFFER_STATUS_HEADER)
			throw new UploadReaderException("Not in header");

		readInBuffer();

		if (isEndOfBuffer()) //end of buffer
			throw new UploadReaderException("Error in header");

		while (true) {
			if (m_baBuffer[m_iPtr] == 0x0d
				&& m_baBuffer[m_iPtr + 1] == 0x0a) { //end of line
				m_baTemp[i] = 0;
				m_iPtr += 2;
				break;
			}
			m_baTemp[i++] = m_baBuffer[m_iPtr++];
			if (isEndOfBuffer()) //end of buffer
				throw new UploadReaderException("Error in header.");
		}

		if (m_baBuffer[m_iPtr] == 0x0d
			&& m_baBuffer[m_iPtr + 1] == 0x0a) { //end of header
			m_iPtr += 2;
			m_iBufferStatus = BUFFER_STATUS_BODY;
		}

		return new String(m_baTemp, 0, i);
	}
	protected boolean readInBuffer() throws IOException {
		int i, j;

		//must in multi-part mode
		if (!isMultipart())
			return false;

		if (m_bEndOfIs)
			return false;

		if (m_iPtr < 0) { //read first time
			m_iPtr = 0;

			m_iEndPtr = readInBuffer(m_is, m_baBuffer, 0);
			if (m_iEndPtr < BUFFER_SIZE) {
				m_bEndOfIs = true;
			}

			//ready to read header information
			m_iBufferStatus = BUFFER_STATUS_HEADER;
		} else { //not first time
			if (m_iPtr < SAFE_SIZE)
				//pointer not exceed boundary yet
				return false;

			//move the end of buffer to the beginning
			for (i = 0, j = SAFE_SIZE; i < BOUNDARY_SIZE; i++, j++)
				m_baBuffer[i] = m_baBuffer[j];

			//{set pointers after move
			m_iPtr -= (SAFE_SIZE);
			if (m_iEndPtr < BUFFER_SIZE) {
				m_iEndPtr -= (SAFE_SIZE);
				return true;
			}
			//}

			if (m_bEndOfIs) //no data to read
				return false;

			m_iEndPtr = readInBuffer(m_is, m_baBuffer, BOUNDARY_SIZE);
			if (m_iEndPtr < BUFFER_SIZE) {
				m_bEndOfIs = true;
			}
		}

		return true;
	}
	static protected int readInBuffer(InputStream is, byte[] ba, int iFrom) throws IOException {
		int iLeft = ba.length - iFrom;

		while (iLeft != 0) {
			int iLen = is.read(ba, iFrom, iLeft);
			if (iLen == -1) {
				return iFrom;
			} else {
				iFrom = iFrom + iLen;
				iLeft = iLeft - iLen;
			}
		}
		return iFrom;
	}
	/**
	 * 跳过正文段中的文件。
	 */
	public void skipFile() throws UploadReaderException, IOException {
		while(m_iBufferStatus == BUFFER_STATUS_FILE) {
			getBodyChar();
		}
	}
}

⌨️ 快捷键说明

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