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

📄 partinputstream.java

📁 很好的文件处理程序
💻 JAVA
字号:
// Copyright (C) 1999-2001 by Jason Hunter <jhunter_AT_acm_DOT_org>.// All rights reserved.  Use of this class is limited.// Please see the LICENSE for more information.package com.oreilly.servlet.multipart;import java.io.FilterInputStream;import java.io.IOException;import javax.servlet.ServletInputStream;/** * A <code>PartInputStream</code> filters a <code>ServletInputStream</code>,  * providing access to a single MIME part contained with in which ends with  * the boundary specified.  It uses buffering to provide maximum performance. * <p> * Note the <code>readLine</code> method of <code>ServletInputStream</code> * has the annoying habit of adding a \r\n to the end of the last line.  Since * we want a byte-for-byte transfer, we have to cut those chars. This means  * that we must always maintain at least 2 characters in our buffer to allow  * us to trim when necessary. *  * @author Geoff Soutter * @author Jason Hunter * @version 1.4, 2002/11/01, fix for "unexpected end of part" caused by *                           boundary newlines split across buffers * @version 1.3, 2001/05/21, fix to handle boundaries crossing 64K mark * @version 1.2, 2001/02/07, added read(byte[]) implementation for safety * @version 1.1, 2000/11/26, fixed available() to never return negative * @version 1.0, 2000/10/27, initial revision */public class PartInputStream extends FilterInputStream {  /** boundary which "ends" the stream */  private String boundary;    /** our buffer */  private byte [] buf = new byte[64*1024];  // 64k    /** number of bytes we've read into the buffer */  private int count;     /** current position in the buffer */  private int pos;    /** flag that indicates if we have encountered the boundary */  private boolean eof;      /**   * Creates a <code>PartInputStream</code> which stops at the specified   * boundary from a <code>ServletInputStream<code>.   *    * @param in  a servlet input stream.   * @param boundary the MIME boundary to stop at.   */  PartInputStream(ServletInputStream in,                   String boundary) throws IOException {    super(in);    this.boundary = boundary;  }  /**   * Fill up our buffer from the underlying input stream, and check for the    * boundary that signifies end-of-file. Users of this method must ensure    * that they leave exactly 2 characters in the buffer before calling this    * method (except the first time), so that we may only use these characters   * if a boundary is not found in the first line read.   *    * @exception  IOException  if an I/O error occurs.   */  private void fill() throws IOException  {    if (eof)      return;        // as long as we are not just starting up    if (count > 0)    {      // if the caller left the requisite amount spare in the buffer      if (count - pos == 2) {        // copy it back to the start of the buffer        System.arraycopy(buf, pos, buf, 0, count - pos);        count -= pos;        pos = 0;      } else {        // should never happen, but just in case        throw new IllegalStateException("fill() detected illegal buffer state");      }    }        // Try and fill the entire buffer, starting at count, line by line    // but never read so close to the end that we might split a boundary    // Thanks to Tony Chu, tony.chu@brio.com, for the -2 suggestion.    int read = 0;    int boundaryLength = boundary.length();    int maxRead = buf.length - boundaryLength - 2;  // -2 is for /r/n    while (count < maxRead) {      // read a line      read = ((ServletInputStream)in).readLine(buf, count, buf.length - count);      // check for eof and boundary      if (read == -1) {        throw new IOException("unexpected end of part");      } else {        if (read >= boundaryLength) {          eof = true;          for (int i=0; i < boundaryLength; i++) {            if (boundary.charAt(i) != buf[count + i]) {              // Not the boundary!              eof = false;              break;            }          }          if (eof) {            break;          }        }      }      // success      count += read;    }  }    /**   * See the general contract of the <code>read</code>   * method of <code>InputStream</code>.   * <p>   * Returns <code>-1</code> (end of file) when the MIME    * boundary of this part is encountered.   *   * @return     the next byte of data, or <code>-1</code> if the end of the   *             stream is reached.   * @exception  IOException  if an I/O error occurs.   */  public int read() throws IOException {    if (count - pos <= 2) {      fill();      if (count - pos <= 2) {        return -1;      }    }    return buf[pos++] & 0xff;  }  /**   * See the general contract of the <code>read</code>   * method of <code>InputStream</code>.   * <p>   * Returns <code>-1</code> (end of file) when the MIME   * boundary of this part is encountered.   *   * @param      b     the buffer into which the data is 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.   * @exception  IOException  if an I/O error occurs.   */  public int read(byte b[]) throws IOException {    return read(b, 0, b.length);  }  /**   * See the general contract of the <code>read</code>   * method of <code>InputStream</code>.   * <p>   * Returns <code>-1</code> (end of file) when the MIME    * boundary of this part is encountered.   *   * @param      b     the buffer into which the data is read.   * @param      off   the start offset of the data.   * @param      len   the maximum number of bytes 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.   * @exception  IOException  if an I/O error occurs.   */  public int read(byte b[], int off, int len) throws IOException  {    int total = 0;    if (len == 0) {      return 0;    }    int avail = count - pos - 2;    if (avail <= 0) {      fill();      avail = count - pos - 2;      if(avail <= 0) {        return -1;      }    }    int copy = Math.min(len, avail);    System.arraycopy(buf, pos, b, off, copy);    pos += copy;    total += copy;          while (total < len) {      fill();      avail = count - pos - 2;      if(avail <= 0) {        return total;      }      copy = Math.min(len - total, avail);      System.arraycopy(buf, pos, b, off + total, copy);      pos += copy;      total += copy;    }    return total;  }  /**   * Returns the number of bytes that can be read from this input stream   * without blocking.  This is a standard <code>InputStream</code> idiom   * to deal with buffering gracefully, and is not same as the length of the   * part arriving in this stream.   *   * @return     the number of bytes that can be read from the input stream   *             without blocking.   * @exception  IOException  if an I/O error occurs.   */  public int available() throws IOException {    int avail = (count - pos - 2) + in.available();    // Never return a negative value    return (avail < 0 ? 0 : avail);  }  /**   * Closes this input stream and releases any system resources    * associated with the stream.    * <p>   * This method will read any unread data in the MIME part so that the next    * part starts an an expected place in the parent <code>InputStream</code>.   * Note that if the client code forgets to call this method on error,   * <code>MultipartParser</code> will call it automatically if you call    * <code>readNextPart()</code>.   *   * @exception  IOException  if an I/O error occurs.   */  public void close() throws IOException {    if (!eof) {      while (read(buf, 0, buf.length) != -1)        ; // do nothing    }  }}

⌨️ 快捷键说明

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