java文件上传和下载(原创,根据RFC1867分析得到)

来源:互联网 发布:word软件损坏怎么办 编辑:程序博客网 时间:2024/05/21 08:58


import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class HttpUtil {

 /*
  * binnary strut is: 1. [seperater] + 0x0D0A + 2. [header info,i.e.
  * Disposition,name,filename...seperate is ;] + 0x0D0A+ 3.
  * [Content-Type:xxx] + 0x0D0A + 0x0D0A 4. [Data bytes] + 0x0D0A + >> this
  * may be binnary,can not change to string 5. [seperater] + 0x0D0A + 2,3,4
  * repeated 6. [seperater] + 0x0D0A
  *
  */

 /**
  * new line key
  */
 public static byte[]  CRLF   = new byte[]{0x0d, 0x0a};

 /**
  * content key
  */
 public static byte[]  CRLF2   = new byte[]{0x0d, 0x0a, 0x0d, 0x0a};

 /**
  * multipart form keywords
  */
 public static String  MULTI_TYPE  = "multipart/form-data";

 /**
  * normal form keywords
  */
 public static String  NORMAL_TYPE  = "application";

 private String[]   contentDisposition;

 private String[]   contentType;

 private byte[][]   data;

 private String[]   fieldString;

 private String[]   filename;

 private boolean    isMultipartForm = false;

 private String[]   name;

 private int     paramCount  = 0;

 private HttpServletRequest request;

 private HttpServletResponse response;

 private String[]   value;

 // read the request and set all fields
 /**
  * <pre>
  *  http tools
  * </pre>
  * @param request request
  * @param response response
  * @throws ServletException ServletException
  * @throws IOException
  */
 public HttpUtil(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

  String ct = request.getContentType();
  this.request = request;
  this.response = response;
  if (ct == null) {
   this.isMultipartForm = false;
  } else {
   if (ct.indexOf(HttpUtil.MULTI_TYPE) < 0) {
    this.isMultipartForm = false;
   } else {
    this.initMultipartForm(request, response);
    this.isMultipartForm = true;
   }
  }
 }

 private byte[] copyBytes(byte[] src, int start, int end) {
  byte[] ret = new byte[end - start + 1]; // include the end
  for (int i = start; i <= end; i++)
   ret[i - start] = src[i];
  return ret;
 }
 
 private int countMatchs(byte[] src, byte[] find) {
  int count = 0;
  int pos = 0;
  for (int i = 0; i < src.length - find.length + 1; i++) {
   pos = this.findBytes(src, find, i);
   if (pos >= 0) {
    i = pos + find.length;
    count++;
   } else {
    break;
   }
  }

  return count;
 }

 /**
  * <pre>
  *  download the special file
  * </pre>
  * @param filepath
  * @throws IOException
  */
 public void download(String filepath) throws IOException {
  String filename = this.getFileName(filepath);
  filename = new String(filename.getBytes("EUC-jp"), "EUC-jp");
  File file = new File(filepath);
  response.reset();
  response.setContentType("application/octet-stream; charset=shift-jis");
  response.addHeader("Content-Disposition", "attachment; filename=" + filename);
  response.setContentLength((int) file.length());

  byte[] buffer = new byte[4096];
  BufferedOutputStream output = new BufferedOutputStream(response.getOutputStream());
  BufferedInputStream input = new BufferedInputStream(new FileInputStream(file));
  int n = -1;
  while ((n = input.read(buffer, 0, 4096)) > -1) {
   output.write(buffer, 0, n);
  }
  response.flushBuffer();
  if (input != null)
   input.close();
  if (output != null)
   output.close();

 }

 private int findBytes(byte[] src, byte[] find, int start) {
  int ret = -1;
  boolean match = true;
  for (int i = start; i < src.length - find.length + 1; i++) {
   match = true;
   for (int j = 0; j < find.length; j++) {
    if (src[i + j] != find[j]) {
     match = false;
     break;
    }
   }
   if (match) {
    ret = i;
    break;
   }
  }
  return ret;
 }

 /**
  * <pre>
  * get file's content(byte)
  * </pre>
  * @param paramName
  * @return
  */
 public byte[] getBytes(String paramName) {
  if (!this.isMultipartForm)
   return new byte[0];
  byte[] ret;
  int idx = this.getParamindex(paramName);

  if (idx >= 0) {
   ret = this.data[idx];
  } else {
   ret = new byte[0];
  }
  return ret;
 }

 /**
  * <pre>
  * getContentDisposition
  * </pre>
  * @param paramName
  * @return
  */
 public String getContentDisposition(String paramName){
  if (!this.isMultipartForm)
   return "";
  String ret = "";
  int idx = this.getParamindex(paramName);

  if (idx >= 0) {
   ret = this.contentDisposition[idx];
  }
  return ret;
 }

 /**
  * <pre>
  * getContentType
  * </pre>
  * @param paramName
  * @return
  */
 public String getContentType(String paramName){
  if (!this.isMultipartForm)
   return "";
  String ret = "";
  int idx = this.getParamindex(paramName);

  if (idx >= 0) {
   ret = this.contentType[idx];
  }
  return ret;
 }

 // Get field info
 private void getFieldInfo(byte[] content, int startIndex, byte[] sep, int idx) throws UnsupportedEncodingException {
  int p1, p2;
  p1 = this.findBytes(content, HttpUtil.CRLF2, startIndex) + 4;
  if (p1 < 4)
   return;
  p2 = this.findBytes(content, sep, p1) - 3;
  if (p2 < p1){
   this.data[idx] = new byte[0];
  }else{
   this.data[idx] = this.copyBytes(content, p1, p2);
  }
  this.fieldString[idx] = new String(this.copyBytes(content, startIndex, p1 - 5));
  this.contentDisposition[idx] = this.getHeaderInfo(this.fieldString[idx], "Content-Disposition: ", ";", "/r/n");
  this.name[idx] = this.getHeaderInfo(this.fieldString[idx], "name=/"", "/"", "/r/n");
  this.filename[idx] = getFileName(this.getHeaderInfo(this.fieldString[idx], "filename=/"", "/"", "/r/n"));
  this.contentType[idx] = this.getHeaderInfo(this.fieldString[idx], "Content-Type: ", ";", "/r/n");
  if (this.filename[idx].length() == 0) {
   this.value[idx] = new String(this.data[idx]);
  } else {
   this.value[idx] = "";
  }
  return;
 }

 /**
  * <pre>
  * getFile
  * </pre>
  * @param paramName
  * @return
  */
 public String getFile(String paramName) {
  if (!this.isMultipartForm)
   return "";
  String ret = "";
  int idx = this.getParamindex(paramName);

  if (idx >= 0) {
   ret = this.filename[idx];
  }
  return ret;
 }

 private String getFileName(String path) {
  int p = -1;
  p = path.lastIndexOf("//");
  if (p < 0)
   p = path.lastIndexOf("/");
  if (p < 0)
   return "";
  return path.substring(p + 1);
 }

 private String getHeaderInfo(String header, String prefix, String suffix, String suffix2) {
  int p1, p2;
  p1 = header.indexOf(prefix) + prefix.length();
  if (p1 < prefix.length())
   return "";
  p2 = header.indexOf(suffix, p1);
  if (p2 < 0 && suffix2.length() > 0)
   p2 = header.indexOf(suffix2, p1);
  if (p2 < 0)
   return "";
  return header.substring(p1, p2);
 }

 /**
  * <pre>
  * getParameter
  * </pre>
  * @param paramName
  * @return
  */
 public String getParameter(String paramName) {
  if (!this.isMultipartForm)
   return this.request.getParameter(paramName);
  String ret = "";
  int idx = this.getParamindex(paramName);

  if (idx >= 0) {
   ret = this.value[idx];
  }
  return ret;
 }

 // get the parameter's index
 public int getParamindex(String paramName) {
  int ret = -1;
  for (int i = 0; i < this.paramCount; i++) {
   if (this.name[i].equals(paramName)) {
    ret = i;
    break;
   }
  }

  return ret;
 }

 public String getParamName(int idx){
  if(idx < this.paramCount){
   return this.name[idx];
  }
  return "";
 }
 
 private void initMultipartForm(HttpServletRequest request, HttpServletResponse response) throws ServletException,
   IOException {
  // get all request data
  int iTotalByte;
  int iTotalRead;
  int iReadByte;
  iTotalByte = request.getContentLength();
  iTotalRead = 0;
  iReadByte = 0;
  byte[] Buffer = new byte[iTotalByte];
  if (iTotalByte == 0)
   return;

  // read all data
  for (; iTotalRead < iTotalByte; iTotalRead += iReadByte) {
   iReadByte = request.getInputStream().read(Buffer, iTotalRead, iTotalByte - iTotalRead);
  }

  // Find the seperate string
  byte[] sepString = this.copyBytes(Buffer, 0, this.findBytes(Buffer, HttpUtil.CRLF, 0) + 1);

  this.paramCount = this.countMatchs(Buffer, sepString);
  this.fieldString = new String[this.paramCount];
  this.filename = new String[this.paramCount];
  this.name = new String[this.paramCount];
  this.contentDisposition = new String[this.paramCount];
  this.contentType = new String[this.paramCount];
  this.data = new byte[this.paramCount][];
  this.value = new String[this.paramCount];

  int pos = 0;
  for (int i = 0; i < this.paramCount; i++) {
   this.getFieldInfo(Buffer, pos, sepString, i);
   // find next position
   pos = this.findBytes(Buffer, sepString, pos + sepString.length);
   if (pos < 0)
    break;
  }
 }

 /**
  * <pre>
  * isMultipart
  * </pre>
  * @return
  */
 public boolean isMultipart() {
  return this.isMultipartForm;
 }

 /**
  * <pre>
  * get the field count
  * </pre>
  * @return
  */
 public int size() {
  return this.paramCount;
 }

 /**
  * <pre>
  * save file in templet
  * </pre>
  * @param paramName
  * @return
  * @throws IOException
  */
 public String upload(String paramName) throws IOException {
  if (!this.isMultipartForm)
   return "";
  String fileName = "";
  int idx = this.getParamindex(paramName);
  String prefix = "";
  String suffix = "";
  if (idx >= 0) {
   if (this.filename[idx].length() != 0) {

    int dotPos = this.filename[idx].indexOf('.');
    if (dotPos >= 0) {
     prefix = "tmp" + this.filename[idx].substring(0, dotPos);
     if (dotPos > this.filename[idx].length() - 1) {
      suffix = "";
     } else {
      suffix = this.filename[idx].substring(dotPos + 1);
     }
    } else {
     prefix = "tmp" + this.filename[idx];
     suffix = "";
    }
    File f = File.createTempFile(prefix, suffix);
    fileName = f.getPath();
    FileOutputStream fos = new FileOutputStream(f);
    fos.write(this.data[idx]);
    fos.close();
   }
  }
  return fileName;
 }

 /**
  * <pre>
  * save file in special path
  * </pre>
  * @param paramName
  * @param directory
  * @return
  * @throws IOException
  */
 public String upload(String paramName, String directory) throws IOException {
  if (!this.isMultipartForm)
   return "";
  String fileName = "";
  int idx = this.getParamindex(paramName);
  if (idx >= 0) {
   if (this.filename[idx].length() != 0) {
    File f = new File(directory, this.filename[idx]);
    fileName = f.getPath();
    FileOutputStream fos = new FileOutputStream(f);
    fos.write(this.data[idx]);
    fos.close();
   }
  }
  return fileName;
 }