All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.extra.servlet.multipart.MultipartRequestInputStream Maven / Gradle / Ivy

There is a newer version: 5.8.27
Show newest version
package cn.hutool.extra.servlet.multipart;

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

/**
 * Http请求解析流,提供了专门针对带文件的form表单的解析
* 来自Jodd * * @author jodd.org */ public class MultipartRequestInputStream extends BufferedInputStream { public MultipartRequestInputStream(InputStream in) { super(in); } /** * 读取byte字节流,在末尾抛出异常 * * @return byte * @throws IOException */ public byte readByte() throws IOException { int i = super.read(); if (i == -1) { throw new IOException("End of HTTP request stream reached"); } return (byte) i; } /** * 跳过指定位数的 bytes. * * @param i 跳过的byte数 */ public void skipBytes(int i) throws IOException { long len = super.skip(i); if (len != i) { throw new IOException("Unable to skip data in HTTP request"); } } // ---------------------------------------------------------------- boundary /** part部分边界 */ protected byte[] boundary; /** * 输入流中读取边界 * * @return 边界 * @throws IOException */ public byte[] readBoundary() throws IOException { ByteArrayOutputStream boundaryOutput = new ByteArrayOutputStream(1024); byte b; // skip optional whitespaces while ((b = readByte()) <= ' ') { } boundaryOutput.write(b); // now read boundary chars while ((b = readByte()) != '\r') { boundaryOutput.write(b); } if (boundaryOutput.size() == 0) { throw new IOException("Problems with parsing request: invalid boundary"); } skipBytes(1); boundary = new byte[boundaryOutput.size() + 2]; System.arraycopy(boundaryOutput.toByteArray(), 0, boundary, 2, boundary.length - 2); boundary[0] = '\r'; boundary[1] = '\n'; return boundary; } // ---------------------------------------------------------------- data header protected UploadFileHeader lastHeader; public UploadFileHeader getLastHeader() { return lastHeader; } /** * 从流中读取文件头部信息, 如果达到末尾则返回null * * @param encoding 字符集 * @return 头部信息, 如果达到末尾则返回null * @throws IOException */ public UploadFileHeader readDataHeader(String encoding) throws IOException { String dataHeader = readDataHeaderString(encoding); if (dataHeader != null) { lastHeader = new UploadFileHeader(dataHeader); } else { lastHeader = null; } return lastHeader; } protected String readDataHeaderString(String encoding) throws IOException { ByteArrayOutputStream data = new ByteArrayOutputStream(); byte b; while (true) { // end marker byte on offset +0 and +2 must be 13 if ((b = readByte()) != '\r') { data.write(b); continue; } mark(4); skipBytes(1); int i = read(); if (i == -1) { // reached end of stream return null; } if (i == '\r') { reset(); break; } reset(); data.write(b); } skipBytes(3); return encoding == null ? data.toString() : data.toString(encoding); } // ---------------------------------------------------------------- copy /** * 全部字节流复制到out * * @param out 输出流 * @return 复制的字节数 * @throws IOException */ public int copy(OutputStream out) throws IOException { int count = 0; while (true) { byte b = readByte(); if (isBoundary(b)) { break; } out.write(b); count++; } return count; } /** * 复制字节流到out, 大于maxBytes或者文件末尾停止 * * @param out 输出流 * @param limit 最大字节数 * @return 复制的字节数 * @throws IOException */ public int copy(OutputStream out, int limit) throws IOException { int count = 0; while (true) { byte b = readByte(); if (isBoundary(b)) { break; } out.write(b); count++; if (count > limit) { break; } } return count; } /** * 跳过边界表示 * * @return 跳过的字节数 */ public int skipToBoundary() throws IOException { int count = 0; while (true) { byte b = readByte(); count++; if (isBoundary(b)) { break; } } return count; } /** * @param b byte * @return 是否为边界的标志 * @throws IOException */ public boolean isBoundary(byte b) throws IOException { int boundaryLen = boundary.length; mark(boundaryLen + 1); int bpos = 0; while (b == boundary[bpos]) { b = readByte(); bpos++; if (bpos == boundaryLen) { return true; // boundary found! } } reset(); return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy