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

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

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

其中遇到的问题

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 block
					e.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
	 */
	@Override
	public 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;  
    }  



  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值