将多个文件进行压缩处理,然后传输到服务器

来源:互联网 发布:淘宝订单业务流程 编辑:程序博客网 时间:2024/06/03 06:33

目前项目正需要多个文件压缩上传,在这里遇到一些坑与解决方案。

我这里的问题是从打印机复印,扫描时候的留底文件。在拿到文件路径后,就要根据这个路径拿到文件,进行压缩传输,可供下载。

其中遇到的问题

1、使用这个thumbnailator-0.4.7.jar对图片进行再压缩,会十分损耗资源,以至于在打印机打印完成后,直接卡住。这个压缩工具慎用!

2、在不使用上面这个工具传输的时候,即时原大小的文件,上传速度也是可行的。只是在一次性将流文件直接传输给压缩流,会出现文件流叠加的问题

从而导致文件显示出现问题。解决办法是流在传输的时候,分段传输,这样就不会出现这种问题。

参考资料:@1.http://www.oschina.net/code/snippet_4873_4142

                  @2.http://www.cnblogs.com/tnxk/archive/2011/09/22/2185248.html

@3.http://blog.csdn.net/zx4321/article/details/7712290  

通过下面的方式,就可以将多个图片压缩成一个压缩流。这样就可以灵活操作这个文件流了

/** * 获取多个压缩文件的流文件 * @param bytesList * @param nameList * @param fileList * @param compress * @return * @throws Exception */public static byte[] zipBytes(ArrayList<String> nameList,ArrayList<File> fileList) throws Exception {ByteArrayOutputStream tempByteOStream = null;        BufferedOutputStream tempBufferOStream = null;        ZipOutputStream tempZStream = null;        ZipEntry tempEntry = null;        byte[] tempBytes = null;        tempByteOStream = new ByteArrayOutputStream();        CheckedOutputStream csum1 = new CheckedOutputStream(tempByteOStream, new Adler32());        tempZStream = new ZipOutputStream(csum1);        tempBufferOStream = new BufferedOutputStream(tempZStream);        for(int i=0;i<fileList.size();i++){        FileInputStream in=new FileInputStream(fileList.get(i));        byte [] buff=new byte[1024];        // 输出校验流,采用Adler32更快        tempZStream.setEncoding("UTF-8");        tempEntry = new ZipEntry(nameList.get(i));        tempZStream.putNextEntry(tempEntry);        /*if (compress) {        bytes= CompressPictureTools.compressOfQuality(fileList.get(i), 0);        }*/        /*else{        bytes= CompressPictureTools.compressOfQuality(fileList.get(i), 1);        }*/        int len=0;        while((len=in.read(buff))!=-1){        tempZStream.write(buff, 0, len);        }        }        tempBufferOStream.flush();        tempByteOStream.flush();        tempZStream.closeEntry();        tempZStream.close();        tempBytes = tempByteOStream.toByteArray();        tempByteOStream.close();        tempBufferOStream.close();        return tempBytes;    }
遍历目录文件,获取最终的文件

/** * 遍历文件目录 * @param path */public static void getFiles( URI path )    {ArrayList<String> filelist = new ArrayList<String>();        File root = new File( path );        File[] files = root.listFiles();        System.out.println("======================[AuditSample] File Exists :================"+root);        System.out.println("======================[AuditSample] File listFiles :================"+files);        for ( File file : files )        {            if ( file.isDirectory() )            {                try {getFiles(new URI(file.getAbsolutePath()));} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}                filelist.add( file.getAbsolutePath() );                System.out.println( "显示" + path + "下所有子目录及其文件" + file.getAbsolutePath() );            }else{                System.out.println( "显示" + path + "下所有子目录" + file.getAbsolutePath() );            }        }    }

这里,我采用了多线程处理的方式来处理上传文件,这样就不会影响主线程进行其他操作了


package com.bips.samsung.utils;import java.io.File;import java.io.FileInputStream;import java.net.URI;import java.util.ArrayList;import com.bips.samsung.service.HttpService;import com.bips.samsung.service.impl.HttpServiceImpl;public class UploadFiles implements Runnable{private URI uri;private String sessionId;private String jobId;private String fileType;private String tokenID;public UploadFiles(URI uri,String sessionId,String jobId,String fileType,String tokenID){this.uri=uri;this.sessionId=sessionId;this.jobId=jobId;this.fileType=fileType;this.tokenID=tokenID;}/** * 上传图片压缩包到服务器 * @param uri * @return */@Overridepublic void run() {System.out.println("=========================文件開始上傳!============================"+System.currentTimeMillis());HttpService httpService=new HttpServiceImpl();try {//遍历文件目录下的文件FTPUtils.getFiles(uri);File file=new File(uri);ArrayList<File> fileList=new ArrayList<File>();ArrayList<String> list=new ArrayList<String>();ArrayList<FileInputStream> inputStreamList=new ArrayList<FileInputStream>();FileInputStream filein=null;if(file.exists()){File[] listFiles = file.listFiles();for(int i=0;i<listFiles.length;i++){String absolutePath=listFiles[i].getAbsolutePath();System.out.println("绝对路径为:"+listFiles[i].getAbsolutePath());if(absolutePath.endsWith(".jpg")){File absfil=new File(new URI("file:"+absolutePath));filein=new FileInputStream(absfil);fileList.add(listFiles[i]);inputStreamList.add(filein);list.add(absolutePath.substring(absolutePath.lastIndexOf("/")+1));}}byte[] zipBytes = CommonUtil.zipBytes(list,fileList);//ByteArrayInputStream byteArray=new ByteArrayInputStream();httpService.UploadFile(zipBytes,sessionId,jobId,fileType,tokenID);System.out.println("===========================上傳文件成功======================"+System.currentTimeMillis());}} catch (Exception e) {e.printStackTrace();}}}

自己定义http传输协议,进行文件上传


 /**      * 上传压缩文件      * @param url         * @param params      * @param zipBytes     * @return       * @throws Exception      */public static URLConnection uploadFile(String url, Map<String, String> params, byte [] zipBytes){       final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线          final String endline ="--"+BOUNDARY + "--\r\n";//数据结束标志          HttpURLConnection conn=null;        StringBuffer strBuf1=null;        StringBuffer strBuf2=null;        System.out.println("json字符串信息为\r\n"+JSON.toJSONString(params));        if (params != null && !params.isEmpty()) {          strBuf1= new StringBuffer();          strBuf1.append("--");          strBuf1.append(BOUNDARY);          strBuf1.append("\r\n");          strBuf1.append("Content-Disposition: form-data; name=\"json"+"\"\r\n\r\n");          strBuf1.append(JSON.toJSONString(params));          strBuf1.append("\r\n");         strBuf1.append("--");         strBuf1.append(BOUNDARY);        strBuf1.append("\r\n");        }          if(zipBytes.length>0){        strBuf2= new StringBuffer();         strBuf2.append("Content-Disposition: form-data; name=\"file"+"\"; filename=\"copyOrScan.zip"+"\"\r\n");        strBuf2.append("Content-Type: image/jpeg/zip" + "\r\n\r\n");        }        int dataLength = strBuf1.toString().getBytes().length+strBuf2.length()+zipBytes.length;        try {        //封装请求内容        URL url1 = new URL(url);          conn= (HttpURLConnection) url1.openConnection();          conn.setRequestMethod("POST");        conn.setDoOutput(true);        conn.setConnectTimeout(5000);          conn.setReadTimeout(30000);          conn.setDoOutput(true);          conn.setDoInput(true);          conn.setUseCaches(false);         //设置请求头        conn.setRequestProperty("Accept", "Accept: text/html, application/xaml+xml,*/*");            conn.setRequestProperty("Content-type", "multipart/form-data; boundary="+ BOUNDARY);            conn.setRequestProperty("Content-Length", dataLength+"");          conn.connect();                DataOutputStream ds = new DataOutputStream(conn.getOutputStream());        ds.write(strBuf1.toString().getBytes("UTF-8"));         ds.write(strBuf2.toString().getBytes("UTF-8")); InputStream in=new ByteArrayInputStream(zipBytes);int buffSize=1024;int length=-1;byte [] buff=new byte[buffSize];while((length=in.read(buff))!=-1){ds.write(buff,0,length);}System.out.println("================字节流总大小为==============="+zipBytes.length);ds.flush();ds.write("\r\n".getBytes("UTF-8"));ds.write(endline.getBytes("UTF-8"));ds.write("\r\n".getBytes("UTF-8"));conn.getResponseCode(); // 为了发送成功  ds.close();return conn;  } catch (Exception e) {e.printStackTrace();}        return null;        }


另外还有一种表单上传文件的方式

/**      * 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:      *   <FORM METHOD=POST ACTION="http://192.168.0.200:8080/ssi/fileload/test.do" enctype="multipart/form-data">             <INPUT TYPE="text" NAME="name">             <INPUT TYPE="text" NAME="id">             <input type="file" name="imagefile"/>             <input type="file" name="zip"/>          </FORM>      * @param path 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080这样的路径测试)      * @param params 请求参数 key为参数名,value为参数值      * @param file 上传文件      */      @SuppressWarnings("resource")public static boolean uploadFiles(String path, Map<String, String> params, FormFile[] files) throws Exception{               final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线          final String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志                    int fileDataLength = 0;          if(files!=null&&files.length!=0){              for(FormFile uploadFile : files){//得到文件类型数据的总长度                  StringBuilder fileExplain = new StringBuilder();                  fileExplain.append("--");                  fileExplain.append(BOUNDARY);                  fileExplain.append("\r\n");                  fileExplain.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");                  fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");                  fileExplain.append("\r\n");                  fileDataLength += fileExplain.length();                  if(uploadFile.getInStream()!=null){                      fileDataLength += uploadFile.getFile().length();                  }else{                      fileDataLength += uploadFile.getData().length;                  }              }          }          StringBuilder textEntity = new StringBuilder();          if(params!=null&&!params.isEmpty()){              for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型参数的实体数据                  textEntity.append("--");                  textEntity.append(BOUNDARY);                  textEntity.append("\r\n");                  textEntity.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");                  textEntity.append(entry.getValue());                  textEntity.append("\r\n");              }          }          //计算传输给服务器的实体数据总长度          int dataLength = textEntity.toString().getBytes().length + fileDataLength +  endline.getBytes().length;                    URL url = new URL(path);          int port = url.getPort()==-1 ? 80 : url.getPort();          Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);                  OutputStream outStream = socket.getOutputStream();          //下面完成HTTP请求头的发送          String requestmethod = "POST "+ url.getPath()+" HTTP/1.1\r\n";          outStream.write(requestmethod.getBytes());          String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";          outStream.write(accept.getBytes());          String language = "Accept-Language: zh-CN\r\n";          outStream.write(language.getBytes());          String contenttype = "Content-Type: multipart/form-data; boundary="+ BOUNDARY+ "\r\n";          outStream.write(contenttype.getBytes());          String contentlength = "Content-Length: "+ dataLength + "\r\n";          outStream.write(contentlength.getBytes());          String alive = "Connection: Keep-Alive\r\n";          outStream.write(alive.getBytes());          String host = "Host: "+ url.getHost() +":"+ port +"\r\n";          outStream.write(host.getBytes());          //写完HTTP请求头后根据HTTP协议再写一个回车换行          outStream.write("\r\n".getBytes());          //把所有文本类型的实体数据发送出来          outStream.write(textEntity.toString().getBytes());                   //把所有文件类型的实体数据发送出来          if(files!=null&&files.length!=0){              for(FormFile uploadFile : files){                  StringBuilder fileEntity = new StringBuilder();                  fileEntity.append("--");                  fileEntity.append(BOUNDARY);                  fileEntity.append("\r\n");                  fileEntity.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");                  fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");                  outStream.write(fileEntity.toString().getBytes());                  if(uploadFile.getInStream()!=null){                      byte[] buffer = new byte[1024];                      int len = 0;                      while((len = uploadFile.getInStream().read(buffer, 0, 1024))!=-1){                          outStream.write(buffer, 0, len);                      }                      uploadFile.getInStream().close();                  }else{                      outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);                  }                  outStream.write("\r\n".getBytes());              }          }          //下面发送数据结束标志,表示数据已经结束          outStream.write(endline.getBytes());          BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));          if(reader.readLine().indexOf("200")==-1){//读取web服务器返回的数据,判断请求码是否为200,如果不是200,代表请求失败              return false;          }          outStream.flush();          outStream.close();          reader.close();          socket.close();          return true;      }  



2 0