java 解压ZIP时ZIP内多个文件的内容解压到一个文件中去了(创建的最后一个文件),例如有A.java,B.java,C.java;解压出来的内容都到C.java中去,A/B中没内容。我怎样才能保证它的正确解压呢?下面是所有代码,文件大家可以自己在工程内建几个文件,看看效果,帮忙分析一下,多谢!
JDK1.6
没用其它JAR包(ant.jar)。public class ZIPTest {
//解压缩
private static void testInflater(String zip) throws IOException{
FileInputStream fis = new FileInputStream(zip);
CheckedInputStream cis = new CheckedInputStream(fis,new Adler32());
ZipInputStream in = new ZipInputStream(cis);
BufferedInputStream bis = new BufferedInputStream(in);

ZipEntry zi;
Pattern p = Pattern.compile("E:");
//这里解压的时候并没有用到ZipEntry对象,如果要看在压缩的时候对这些文件进去过那些属性设置当然可以用这个对象。
while ((zi = in.getNextEntry()) != null) {
System.out.println(zi.isDirectory());
System.out.println(in.read());
Matcher m = p.matcher(zi.getName());
String destPath = m.replaceFirst("D:");
File file = new File(destPath);
file.getParentFile().mkdirs();
file.createNewFile();
BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream(file));                        
int x,y = 0;
while ((x = bis.read()) != -1) {
System.out.println("Y: " + y++);
bw.write(x);
}
bw.close();
}

bis.close();
}

public static void main(String[] args) throws IOException {
String filePath = "src" + File.separator + "com" + File.separator
+ "java" + File.separator + "j2se" + File.separator + "io"
+ File.separator + "file" + File.separator + "stream"
+ File.separator + "byteStream" + File.separator + "fileIo";
File file = new File(filePath);
File[] fils = file.listFiles();

String zip = "src" + File.separator + "com" + File.separator
+ "java" + File.separator + "j2se" + File.separator + "io"
+ File.separator + "file" + File.separator + "stream"
+ File.separator + "byteStream" + File.separator + "fileZIP.zip";

//testDeflater(fils, zip);
        testInflater(zip);
}
    //压缩
private static void testDeflater(File[] fils, String zip)
throws FileNotFoundException, IOException {
FileOutputStream fos = new FileOutputStream(zip);
//需要维护写入数据校验和的输出流。校验和可用于验证输出数据的完整性。 
CheckedOutputStream cis = new CheckedOutputStream(fos,new Adler32());
System.out.println(cis.getChecksum().getValue());//不知道这个值代表什么意思
//这里它们也经过了一层层的嵌套-经过CheckedOutputStream对象的检测
ZipOutputStream zos = new ZipOutputStream(cis);
//因为压缩底层处理用的是字节,所以最终回到字节处理。
BufferedOutputStream bos = new BufferedOutputStream(zos);

//zos.setComment("A test java ziping");
for (int i = 0; i < fils.length; i++) {
BufferedReader in = new BufferedReader(new FileReader(fils[i].getAbsolutePath()));
//一个路径一个路径的放,最后全部放到fileZIP.zip文件中了。
zos.putNextEntry(new ZipEntry(fils[i].getAbsolutePath()));
int c;
while ((c = in.read()) != -1) {
bos.write(c);
}
in.close();
}
bos.close();
}
}

解决方案 »

  1.   

    为什么要压缩绝对路径?zos.putNextEntry(new ZipEntry(fils[i].getAbsolutePath()));应该改为zos.putNextEntry(new ZipEntry(fils[i].getName()));
      

  2.   

    这个是我用的..你可以参考一下
    import java.io.BufferedInputStream;   
    import java.io.BufferedOutputStream;   
    import java.io.File;   
    import java.io.FileInputStream;   
    import java.io.FileOutputStream;     
    import java.io.InputStream;   
    import java.io.OutputStream;   
    import java.util.ArrayList;   
    import java.util.Enumeration;   
    import java.util.List;
    import org.apache.tools.zip.*;    //需要ant.jar,使用这个包是为了防止中文乱码问题public class ZipUtil {
        public static final String ZIP_FILEPATH = "d:\\";                 //压缩的文件路径
        public static final String ZIP_DIR = "d:\\TestPath\\";            //压缩文件后存放的路径
        public static final int BUFFER = 1024 ;                              //缓存大小   
           
        /**  
        * zip压缩功能.  压缩文件夹下所有文件
        * 压缩baseDir(文件夹目录)下所有文件,包括子目录 
        * @param  baseDir 需要压缩的文件夹目录
        * @param  fileName 压缩后存放的文件夹+文件名
        * @throws Exception  
        */  
        public static void zipAllInFolderFile(String baseDir,String fileName) throws Exception{
         
            List fileList=getSubFiles(new File(baseDir));
            
            ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(fileName));
            
            ZipEntry ze=null;
            
            byte[] buf=new byte[BUFFER];
            
            int readLen=0;
            
            for(int i = 0; i <fileList.size(); i++) {   
                File f=(File)fileList.get(i);   
                ze=new ZipEntry(getAbsFileName(baseDir, f));   
                ze.setSize(f.length());   
                ze.setTime(f.lastModified());      
                zos.putNextEntry(ze);   
                InputStream is=new BufferedInputStream(new FileInputStream(f));   
                while ((readLen=is.read(buf, 0, BUFFER))!=-1) {   
                    zos.write(buf, 0, readLen);   
                } 
                
                is.close();   
            }   
            
            zos.close();   
        }
        
        /**
         * zipDifferFolderFile 
         * @param srcFileNames 不同目录下的文件(多个或者一个)
         * @param fileName 新生成Zip文件的名字
         * @throws Exception
         */
        public static void zipDifferFolderFile(List<String> srcFileNames,String fileName) throws Exception{
         
            ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(fileName));
            
            ZipEntry ze=null;
            
            byte[] buf=new byte[BUFFER];
            
            int readLen=0;
            
            for(int i = 0; i <srcFileNames.size(); i++) {   
                
             String tempFileName = srcFileNames.get(i);
             File f = new File(tempFileName);
             
                ze=new ZipEntry(getAbsFileName(f));   
                ze.setSize(f.length());   
                ze.setTime(f.lastModified());      
                zos.putNextEntry(ze);   
                InputStream is=new BufferedInputStream(new FileInputStream(f));   
                while ((readLen=is.read(buf, 0, BUFFER))!=-1) {   
                    zos.write(buf, 0, readLen);   
                } 
                
                is.close();   
            }   
            
            zos.close();   
        }
           
        /**
        * 由于给定的需要压缩的文件是带路径的,所以压缩到zip文件中需要取掉绝对路径
        * 该方法用于zipAllInFolderFile()中
        * @param baseDir java.lang.String 根目录  
        * @param realFileName java.io.File 实际的文件名  
        * @return 相对文件名  
        */  
        private static String getAbsFileName(String baseDir, File realFileName){   
            File real=realFileName;   
            File base=new File(baseDir);   
            String ret=real.getName();   
            while (true) {   
                real=real.getParentFile();   
                if(real==null)    
                    break;   
                if(real.equals(base))    
                    break;   
                else  
                    ret=real.getName()+"/"+ret;   
            }   
            return ret;   
        }
        
         /**    * 重载方法,该方法用于zipDifferFolderFile()方法中
        * @param realFileName java.io.File 实际的文件名  
        * @return 相对文件名  
        */ 
        private static String getAbsFileName(File realFileName){   
            File real=realFileName;   
            String ret=real.getName();
            return ret;   
        }
           
        /**  
        * 取得指定目录下的所有文件列表,包括子目录.  
        * @param baseDir File 指定的目录  
        * @return 包含java.io.File的List  
        */  
        private static List getSubFiles(File baseDir){   
            List ret=new ArrayList();   
            File[] tmp=baseDir.listFiles();   
            for (int i = 0; i <tmp.length; i++) {   
                if(tmp.isFile())   
                    ret.add(tmp);   
                if(tmp.isDirectory())   
                    ret.addAll(getSubFiles(tmp));   
            }   
            return ret;   
        }   
           
        /**  
        * 解压缩功能.  
        * 将ZIP_FILENAME文件解压到ZIP_DIR目录下.  
        * @throws Exception  
        */  
        public static void upZipFile(String fileName) throws Exception{ 
         
            ZipFile zfile=new ZipFile(ZIP_FILEPATH+fileName);   
            Enumeration zList=zfile.getEntries();   
            ZipEntry ze=null;   
            byte[] buf=new byte[1024];   
            while(zList.hasMoreElements()){   
                ze=(ZipEntry)zList.nextElement();          
                if(ze.isDirectory()){   
                    File f=new File(ZIP_DIR+ze.getName());   
                    f.mkdir();   
                    continue;   
                }
                OutputStream os=new BufferedOutputStream(new FileOutputStream(getRealFileName(ZIP_DIR, ze.getName())));   
                InputStream is=new BufferedInputStream(zfile.getInputStream(ze));   
                int readLen=0;   
                while ((readLen=is.read(buf, 0, 1024))!=-1) {   
                    os.write(buf, 0, readLen);   
                }   
                is.close();   
                os.close();    
            }   
            zfile.close();   
        }   
      
        /**  
        * 给定根目录,返回一个相对路径所对应的实际文件名.  
        * @param baseDir 指定根目录  
        * @param absFileName 相对路径名,来自于ZipEntry中的name  
        * @return java.io.File 实际的文件  
        */  
        public static File getRealFileName(String baseDir, String absFileName){   
            String[] dirs=absFileName.split("/"); 
           
            File ret=new File(baseDir);   
            if(dirs.length>1){   
                for (int i = 0; i < dirs.length-1;i++) {   
                    ret=new File(ret, dirs);   
                }   
                if(!ret.exists())   
                    ret.mkdirs();   
                ret=new File(ret, dirs[dirs.length-1]);   
                return ret;   
            }else{
             return new File(baseDir+absFileName);
            }
            //return ret;   
        }   
       
      }
      

  3.   

        多谢各位,我知道是什么原因了,是我在压缩的时候在程序的最后,准确来说是在压缩多个文件时那个for循环后面没有zos.close(),也就没有将流中的数据完全刷到文件中去,从而导致了问题的发生。