怎样用java实现压缩传输文件夹

来源:互联网 发布:win10 uac 知乎 编辑:程序博客网 时间:2024/05/01 08:54

         最近碰到个需求,为了提高传输速度,打算压缩、传输、解压同时进行,即服务端压缩、传输并发执行,客户端接收、解压并发进行;折腾来折腾去,倒也有些进展。下面先贴出代码,结合代码讲解。


服务端代码:

public class Hzipserver extends Thread {//无论文件,还是文件夹都是一个ZipEntry。/** * 这里默认所有文件都可以读写,但在实际应用中, * 为了程序的健壮性,必须判断文件是否可读、可写, * 是否是隐藏文件等,在安卓里这种情形很常见。 * 例如,不可读的文件,自然也就没法传输了。 * @param file  要传送的文件夹。 * @param zos   包装后的socket的outputstream * @param b     缓存所用。一个容器。 */private void zipEntry(File file,ZipOutputStream zos,byte[] b){if(file.isDirectory())//如果文件是目录,就没什么需要传输的了,//只要在zos里放进一个ZipEntry,然后递归它里面的文件{//ZipEntry有个方法isDirectory(),可判断该ZipEntry表示的//而是不是目录(文件夹),依据就是该ZipEntry的name是不是以“/”结尾的。ZipEntry ze=new ZipEntry(file.getAbsolutePath()+"/");try {zos.putNextEntry(ze);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}File[] files=file.listFiles();for(File f:files){zipEntry(f, zos,b);}}else{ZipEntry ze=new ZipEntry(file.getAbsolutePath());try {zos.putNextEntry(ze);FileInputStream ins=new FileInputStream(file);int length=-1;while(  (length=ins.read(b))>-1 ){zos.write(b, 0, length);zos.flush();}zos.closeEntry();zos.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}@Overridepublic void run() {// TODO Auto-generated method stub// TODO Auto-generated method stub   ServerSocket ss = null;       java.net.Socket s=null;       try {ss = new ServerSocket(10100);} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}        while(true)        {        try {s=ss.accept();//要发送出去的文件夹。请注意在不同操作系统上,表示方法可能不一样。File file =new File("D:/zipfolder");OutputStream os=s.getOutputStream();        ZipOutputStream gout=new ZipOutputStream(os);        byte[] b=new byte[1024];        zipEntry(file, gout,b);        s.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}                }}}


客户端代码:

public class Hzipclient extends Thread {@Overridepublic void run() {// TODO Auto-generated method stubtry {Socket s=new Socket("192.168.0.1",10100);InputStream ins=s.getInputStream();ZipInputStream zis=new ZipInputStream(ins);String rootDir=null;//在此次连接中,是否是第一次读到ZipEntry。读到的第一个Entry,就是正在被传输的文件夹。boolean isFirst=true;String savePath="D:"+File.separator+"gitspace"+File.separator;//以上为保存接收到的文件夹的位置。//如,服务端传输的文件夹是D:\zipfolder,则该文件夹在客户端将保存在D:\gitspace\。//为了良好的移植性,这里用File.separator,//因为分隔符在不同的操作系统上,可能不一样。ZipEntry ze=null;ZipOutputStream zos=null;FileOutputStream fos=null;OutputStream os=null;byte[] b=new byte[1024];int length=-1;while( (ze=zis.getNextEntry())!=null  ){String name=ze.getName();File file=null;if(ze.isDirectory()){if(isFirst){isFirst=false;//这里可能移植性不好,我还没研究透,暂用此法。String[] temp=name.split("\\\\");//文件夹的名字。参看服务端代码可知,这个名字是“/”结尾的。String selfName=temp[temp.length-1];//去掉“/”,这里才是真正的文件夹的名字。//后面接收到的文件将要以rootDir为参照物,确定保存位置。rootDir=selfName.substring(0, selfName.length()-1);//到了这里,这个文件夹的路径其实就是D:\gitspace\zipfolder了。file=new File(savePath+selfName);}int index=name.indexOf(rootDir);//如,该文件在服务端的位置是D:\zipfolder\a.txt,则tempDir=zipfolder\a.txtString tempDir=name.substring(index,name.length());//两者拼合,该文件在客户端的保存路径也就是D:\gitspace\zipfolder\a.txt了。//相对于ziplolder,该文件的位置未发生变化。file=new File(savePath+tempDir);if(!file.exists()){file.mkdirs();}}else{int index=name.indexOf(rootDir);String tempFileDir=name.substring(index,name.length());file=new File(savePath+tempFileDir);fos=new FileOutputStream(file);while( (length=zis.read(b))>-1  ){fos.write(b, 0, length);}//这句必须有,不然文件多了,打开的文件过多,将会发生异常fos.close();}}s.close();} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}


       其实这么做到底是不是算压缩、传输、解压同时进行,我还没研究透。尤其发现,我发送出来的字节数其实跟原文件的字节数是一样的,并没有想象中可能会体积变小,而客户端接收到的字节数也是原文件的体积大小。有明白的还请赐教。



0 0
原创粉丝点击