java客户端运用http向服务器批量传输文件

这几天做项目遇到一个问题,用java swing做的客户端向服务器批量传输文件,传输量达到200M时会报堆溢出的异常。代码如下:
byte[] content = null;
            try {
                fin = new FileInputStream(file);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                byte[] temp = new byte[1024];
                int size = 0;
                while ((size = fin.read(temp)) != -1) {
                    out.write(temp, 0, size);
                }
                fin.close();
                content = out.toByteArray();
            } catch (Exception e) {
                e.printStackTrace();
            }
批量上传是,用循环的方式将每个文件流数组content发送到服务器,把文件名也发送到服务器,服务器再将数组content写入文件。这种方法在文件量较大时java虚拟机奔溃。
我的解决方法是用http的方法上传,依然是做一个循环,代码如下:(点击swing界面上的上传按钮,执行下面的这个线程)
private String serveraddress;
private static String HTTPHEAD = "http://";
private static String HTTPTAIL = ":8080/wms//ReceiveUploadFile";
private String uploadedfilesforlog = "";//记录上传的文件名,用于日志保存
Runnable upload = new Runnable() {
public void run() {
File[] files = fileChooser.getSelectedFiles();
            if(files.length>50){
            JOptionPane.showMessageDialog(uploadFileDialog.this,"一次上传文件数量不能超过50个");
            uploadButton.setEnabled(true);
return;
            }
StringBuffer uploadedfiles = new StringBuffer();
if (null == files || files.length == 0) {
JOptionPane.showMessageDialog(uploadFileDialog.this,"您没有选择语音文件,请选择语音文件后上传。");
uploadButton.setEnabled(true);
return;
}
serveraddress = dsclient.getServerAddrss();
for (int i = 0; i < files.length; i++) {
String targetURL = null;// TODO 指定URL
File targetFile = null;// TODO 指定上传文件
targetFile = files[i];
targetURL = HTTPHEAD + serveraddress + HTTPTAIL; // servleturl
PostMethod filePost = new PostMethod(targetURL);
//filePost.getParams().setContentCharset("utf-8");
logger.info(filePost.getParams().getContentCharset());
try {
// 通过以下方法可以模拟页面参数提交
Part[] parts = { new FilePart(targetFile.getName(),targetFile) };
filePost.setRequestEntity(new MultipartRequestEntity(parts,filePost.getParams()));
HttpClient client = new HttpClient();
client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
int status = client.executeMethod(filePost);
if (status == HttpStatus.SC_OK) {
if (saveAudioFileToDatabase(files[i]).equals("upload failed")) {
continue;
}
uploadedfilesforlog += uploadedfilesforlog.equals("")?files[i].getName():"," + files[i].getName();
saveLog("success");
logger.info(files[i].getName()+"上传成功");
uploadedfiles.append("[");
uploadedfiles.append(files[i].getName());
uploadedfiles.append("]");
if ((i + 1) % 5 == 0) {
uploadedfiles.append("<BR>");
}
} else {
logger.info("上传失败");
// 上传失败
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
filePost.releaseConnection();
}
}
if (uploadedfiles.length() == 0) {
return;
}
uploadButton.setEnabled(true);
String tip = "<html>语音文件<font color='red'><b>"+ uploadedfiles.toString() + "</b></font>上传成功!</html>";
JOptionPane.showMessageDialog(uploadFileDialog.this, tip);
uploadFileDialog.this.setVisible(false);
uploadFileDialog.this.dispose();
audioFileManagement.loadList();
}
};
服务器短接受代码:
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
public class ReceiveUploadFile extends HttpServlet
{
  private static final long serialVersionUID = 1L;
  Logger logger = Logger.getLogger(ReceiveUploadFile.class);
  private String uploadPath = "/var/lib/X1000/sounds/audiofile/";
  private String tempPath = "/var/lib/X1000/sounds/audiofile/buffer/";
  File tempPathFile;
  public void init()
    throws ServletException
  {
    File uploadFile = new File(this.uploadPath);
    if (!(uploadFile.exists()))
      uploadFile.mkdirs();
    File tempPathFile = new File(this.tempPath);
    if (!(tempPathFile.exists()))
      tempPathFile.mkdirs();
  }
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    doPost(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
  {
    DiskFileItemFactory factory;
    try
    {
      factory = new DiskFileItemFactory();
      factory.setSizeThreshold(4096);
      factory.setRepository(this.tempPathFile);
      ServletFileUpload upload = new ServletFileUpload(factory);
      upload.setSizeMax(41943040L);
      List items = upload.parseRequest(request);
      Iterator i = items.iterator();
      while (i.hasNext())
      {
        FileItem fi = (FileItem)i.next();
        String fileName = fi.getName();
        if (fileName != null)
        {
          String filename = new String(fi.getName().getBytes(), "utf-8");
          this.logger.info("=======================接收到语音文件的文件名:" + filename);
          File fullFile = new File(filename);
          File savedFile = new File(this.uploadPath, fullFile.getName());
          fi.write(savedFile);
        }
      }
      System.out.print("upload succeed");
    }
    catch (Exception e)
    {
      System.out.println(e.getMessage());
      e.printStackTrace();
    }
  }
}
web.xml
<servlet>
  <servlet-name>ReceiveUploadFile</servlet-name>
  <display-name>ReceiveUploadFile</display-name>
  <description>ReceiveUploadFile</description>
  <servlet-class>com.gohigh.centrex.common.ReceiveUploadFile</servlet-class>
  <load-on-startup>4</load-on-startup>
  </servlet>
-<servlet-mapping>
  <servlet-name>ReceiveUploadFile</servlet-name>
  <url-pattern>/ReceiveUploadFile</url-pattern>
  </servlet-mapping>

依赖的jar包:commons-httpclient-3.1.jar,commons-fileupload-1.2.1.jar,commons-codec-1.3.jar,
遇到的问题:中文乱码问题,由于commons-httpclient-3.1.jar包中的默认编码方式不是UTF-8,所以发送到服务器的中文文件名服务器解析乱码。看了好多网上的方法
都是设置编码方式,但是我试了,还是不行,最终只能修改jar包中的源代码了。一个现成的utf-8的jar包下载地址:

http://download.csdn.net/detail/wcbkanaz/3697109,感谢热心网友。

另外,修改源码的时候把里面的编码都改成自己想要的编码,这样才确保服务器能正确解析。

http://download.csdn.net/detail/yuanxw44/4028099,这个地址可以下载源码,解压后把里面java目录下的文件拷到eclipse的src目录下即可,需要依赖两个包,

commons-logging.jar和commons-codec.jar,修改后用fatjar重新打一次即可。



commons-httpclient-3.1.jar

commons-fileupload-1.2.1.

commons-fileupload-1.2.1.

commons-codec-1.3.jar

上一篇:JSONArray中按某字段排序,解决JSONObject.fromObject()报错问题


下一篇:上传文件中 MultipartFile 转为 File