那我现在有问题问下大家啊!一个基本的问题啊!关于用java解压缩zip文件,大家看下哪里写错了!我实在是不知道该怎么改我的程序了:
我要求把e:\\XML_exa.zip解压到e:\XML_exa文件下
package com.javaftp;import java.io.*;import java.util.zip.*;public class UnZip {static final int BUFFER = 2048;public static void main (String argv[]) {try {BufferedOutputStream dest = null;FileInputStream fis = new FileInputStream("e:\\XML_exa.zip");ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));ZipEntry entry;while((entry = zis.getNextEntry()) != null) {System.out.println("Extracting: " +entry);int count;byte data[] = new byte[BUFFER];/*write the files to the disk
FileOutputStream(String name) 
          创建一个向具有指定名称的文件中写入数据的输出文件流。
          */
FileOutputStream fos = new FileOutputStream("e:\\XML_exa");/*BufferedOutputStream(OutputStream out, int size) 
创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输出流。
*/
dest = new BufferedOutputStream(fos, BUFFER);while ((count = zis.read(data, 0, BUFFER)) != -1) {dest.write(data, 0, count);}
//刷新此缓冲的输出流。
dest.flush();dest.close();}zis.close();} catch(Exception e) {e.printStackTrace();}}}
为什么我
e:\\XML_exa文件为0字节,我到底哪里写错了?怎么改呢?请大家把改好的程序帖出来,最好测试过的!谢谢!

解决方案 »

  1.   

    你的程序,我运行了一下,基本正确,但:
    FileOutputStream fos = new FileOutputStream("e:\\XML_exa");
    输出文件名是固定的,写第二个文件时,第一个文件的内容就被覆盖了。建议,先创建一个子目录,如"e:\\XML_exa",
    再FileOutputStream fos = new FileOutputStream("e:\\XML_exa\\" + entry.getName());
      

  2.   

    我没创建子目录,只改了这一句:
    FileOutputStream fos = new FileOutputStream("e:\\XML_exa_" + entry.getName());
    在e盘下生成了若干个以"XML_exa_"开头的文件。
      

  3.   

    已测试public static void main(String argv[]) {
            try {
                String fileName = "d:\\XML_exa.fff.p.zip";  //待解压缩的文件名
                File file = new File(fileName);
                
                //从文件名中提取出子目录(路径)名
                int n=fileName.lastIndexOf(".");
                String folderName = fileName.substring(0,n);
                File folder = new File(folderName);
                folder.mkdir(); //创建子目录(路径)
                
                System.out.println(folderName);
                BufferedOutputStream dest = null;
                FileInputStream fis = new FileInputStream(file);
                ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
                ZipEntry entry;
                
                while((entry = zis.getNextEntry()) != null) {
                    System.out.println("Extracting: " +entry);
                    int count;
                    byte data[] = new byte[BUFFER];
                    /*write the files to the disk
                    FileOutputStream(String name)
                    创建一个向具有指定名称的文件中写入数据的输出文件流。
                     */
                    FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry.getName());
                    /*BufferedOutputStream(OutputStream out, int size)
                    创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输出流。
                     */
                    dest = new BufferedOutputStream(fos, BUFFER);
                    while ((count = zis.read(data, 0, BUFFER)) != -1) {
                        dest.write(data, 0, count);
                    }
                    //刷新此缓冲的输出流。
                    dest.flush();
                    dest.close();
                }
                zis.close();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
      

  4.   

    我写的压缩程序同样遇到了路经问题!package com.javaftp;
    import java.io.*;import java.util.zip.*;
    public class Zip { 
    public static void main(String[] args) {   
    try {           
    FileOutputStream f = new FileOutputStream("f:\\810.zip");      
      ZipOutputStream out = new ZipOutputStream(new DataOutputStream(f));      
    for (int i = 0; i < args.length; i++) {   
    System.out.println("Writing file " + args[i]);   
    DataInputStream in = new DataInputStream(new FileInputStream(args[i])); 
    out.putNextEntry(new ZipEntry(args[i])); 
    int c;              
    while ((c = in.read()) != -1)   
    out.write(c);             
                      in.close();           
      }           
    out.close();     
    } catch (Exception e) {       
    e.printStackTrace();      
    }    
    }
    }
    /*测试数据:命令行方式
    e:\>javac com\javaftp\Zip.java
    e:\>java com.javaftp.Zip f:\html\*.*
    */我html文件夹下面是四个.html文件,为什么压缩文件810.zip的路经是810.zip\f:\html 请问中间的那个f:是怎么回事啊??怎样去掉那个f:呢?我测试java com.javaftp.Zip f:\html\*.*中间的f肯定要写的啊!
      

  5.   

    String entry=args[i];//把前边的“x:\”去掉
    if (entry.charAt(1)==':') 
       entry=entry.substring(3);out.putNextEntry(new ZipEntry(entry));
      

  6.   

    你那个要压缩程序如果要压整个文件夹的所有文件的话得递归:public  static void ZipFiles(String pm_sFilePath)
    {
    try
    {
    FileOutputStream f = new FileOutputStream("f:\\810.zip",true);      
      ZipOutputStream out = new ZipOutputStream(new DataOutputStream(f));      
       
      File file = new File(pm_sFilePath);
     
      if(file.isFile())
      {
      DataInputStream in = new DataInputStream(new FileInputStream(file.getAbsolutePath())); 
      out.putNextEntry(new ZipEntry(file.getName())); 
      int c;              
      while ((c = in.read()) != -1)
      {
      out.write(c);
      }
      in.close();
      out.close();   
      }
      else
      {
      String [] fileNames = file.list();
      for(int j=0;j<fileNames.length;j++)
      {
      File subFile = new File(pm_sFilePath+"\\"+fileNames[j]);
      if(subFile.isFile())
      {
      DataInputStream in = new DataInputStream(new FileInputStream(subFile.getAbsolutePath())); 
      out.putNextEntry(new ZipEntry(subFile.getName())); 
      int c;              
      while ((c = in.read()) != -1)
      {
      out.write(c);
      }
      in.close();
      }
      else if(subFile.isDirectory())
      {
      ZipFiles(fileNames[j]);
      }
      }
     
                
    out.close();   
     
      }
     
     
    }
    catch(IOException es)
    {
    System.out.println("IO操作异常!");
    es.printStackTrace();

    }
    }
      

  7.   

    trumplet(检查) 大哥:
    我用你的程序测试为什么就是错的啊!package com.javaftp;
    import java.io.*;import java.util.zip.*;
    public class UnZip { 
    static final int BUFFER = 2048;public static void main(String argv[]) {
        try {
            String fileName = "f:\\new.zip";  //待解压缩的文件名
            File file = new File(fileName);
            
            //从文件名中提取出子目录(路径)名
            int n=fileName.lastIndexOf(".");
            String folderName = fileName.substring(0,n);
            File folder = new File(folderName);
            folder.mkdir(); //创建子目录(路径)
            
            System.out.println(folderName);
            BufferedOutputStream dest = null;
            FileInputStream fis = new FileInputStream(file);
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            ZipEntry entry;
            
            while((entry = zis.getNextEntry()) != null) {
                System.out.println("Extracting: " +entry);
                int count;
                byte data[] = new byte[BUFFER];
                /*write the files to the disk
                FileOutputStream(String name)
                创建一个向具有指定名称的文件中写入数据的输出文件流。
                 */
                FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry.getName());
                /*BufferedOutputStream(OutputStream out, int size)
                创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输出流。
                 */
                dest = new BufferedOutputStream(fos, BUFFER);
                while ((count = zis.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, count);
                }
                //刷新此缓冲的输出流。
                dest.flush();
                dest.close();
            }
            zis.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    }报错如下:
    f:\new 
    Extracting: html/about.html
    java.io.FileNotFoundException: f:\new\html\about.html (系统找不到指定的路径。)
    at java.io.FileOutputStream.open(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:70)
    at com.javaftp.UnZip.main(UnZip.java:34)f:\\new.zip 是我把我电脑里一个叫html的文件夹压缩而成的,html文件夹下放了几个.html文件。这路经问题到底该如何解决啊!!头疼啊!
      

  8.   

    你的new.zip里有子目录,此前我没考虑到。
    /*write the files to the disk
    FileOutputStream(String name)
    创建一个向具有指定名称的文件中写入数据的输出文件流。
    */
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //加上这4句话:
    String subDirName=folderName + "\\" + new File(entry.getName()).getParent();
    File subDir = new File(subDirName);
    System.out.println(subDir.getAbsolutePath());
    subDir.mkdirs();
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry.getName());
      

  9.   

    trumplet(检查) 大哥,程序还有些问题啊!package com.javaftp;
    import java.io.*;import java.util.zip.*;
    public class UnZip { 
    static final int BUFFER = 2048;public static void main(String argv[]) {
        try {
            String fileName = "f:\\new.zip";  //待解压缩的文件名
            File file = new File(fileName);
            
            //从文件名中提取出子目录(路径)名
            int n=fileName.lastIndexOf(".");
            String folderName = fileName.substring(0,n);
            File folder = new File(folderName);
            folder.mkdir(); //创建子目录(路径)
            
            System.out.println(folderName);
            BufferedOutputStream dest = null;
            FileInputStream fis = new FileInputStream(file);
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            ZipEntry entry;
            
            while((entry = zis.getNextEntry()) != null) {
                System.out.println("Extracting: " +entry);
                int count;
                byte data[] = new byte[BUFFER];
                /*write the files to the disk
                FileOutputStream(String name)
                创建一个向具有指定名称的文件中写入数据的输出文件流。
                 */
                String subDirName=folderName + "\\" + new File(entry.getName()).getParent();
                File subDir = new File(subDirName);
                System.out.println(subDir.getAbsolutePath());
                subDir.mkdirs();   
                FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry.getName());
                /*BufferedOutputStream(OutputStream out, int size)
                创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输出流。
                 */
                dest = new BufferedOutputStream(fos, BUFFER);
                while ((count = zis.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, count);
                }
                //刷新此缓冲的输出流。
                dest.flush();
                dest.close();
            }
            zis.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    }
    程序输出及报错如下:f:\new
    Extracting: html/about.html
    f:\new\html
    Extracting: html/link.html
    f:\new\html
    Extracting: html/photo.html
    f:\new\html
    Extracting: html/profile.html
    f:\new\html
    Extracting: html/
    f:\new\null
    java.io.FileNotFoundException: f:\new\html (拒绝访问。)
    at java.io.FileOutputStream.open(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:70)
    at com.javaftp.UnZip.main(UnZip.java:38)
    我的f盘里是出了个new文件夹,但此文件夹中有两个文件夹,一个叫html,一个叫null,那个null是多余的?
    怎么去除呢?
    而且我发现这个程序不是对每个文件解压缩都起效果的!
    我做的测试:我把html文件夹,11.xml文件,22.txt文件,三个文件做成的aa.zip用上面的程序进行解
    压,我发现存在以下问题:
    1)还是多了一个null文件夹
    2)22.txt文件根本没解压出来!解压后的文件夹aa下面根本没22.txt文件。
    是不是解压程序不支持.txt文件格式?
    如果我换成其它后缀的文件呢?如.cgm,.prot跟格式的文件呢?
      

  10.   

    我测试时,已没有问题,第一次用2个txt文件压缩成1个zip,第二次用2个html和一个子目录(内含另外2个html)压缩成一个zip,至于null,我想,是否是你的zip文件本身的问题呢?
      

  11.   

    while((entry = zis.getNextEntry()) != null ) {     if (entry.isDirectory()) continue;  //加上这句
                    System.out.println("Extracting: " +entry);
                    int count;
                    byte data[] = new byte[BUFFER];
                    /*write the files to the disk
                    FileOutputStream(String name)
                    创建一个向具有指定名称的文件中写入数据的输出文件流。
                     */
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~改下面这几句
                    File f1 = new File(entry.getName());
                    if (f1.getParent()!=null){
                        String subDirName=folderName + "\\" + f1.getParent();
                        File subDir = new File(subDirName);
                        System.out.println(subDir.getAbsolutePath());
                        subDir.mkdirs();
                    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry.getName());
      

  12.   

    trumplet(检查)大哥真是好人啊!看来是多层目录的问题!我把我改好的程序加上了注解您看下,我还有两个问题想问下:package com.javaftp;
    import java.io.*;import java.util.zip.*;
    public class UnZip { 
    static final int BUFFER = 2048;public static void main(String argv[]) {
        try {
            String fileName = "f:\\bb.zip";  //待解压缩的文件名
            
            /*
             * 创建一个File实例file
              
           public class File 为文件和目录路径名的抽象表示形式。
            构造方法File(String pathname) 
            通过将给定路径名字符串转换成抽象路径名来创建一个新 File 实例。
            */
            File file = new File(fileName);
            
            //从文件名中提取出子目录(路径)名
            //lastIndexOf(String str)返回在此字符串中最右边出现的指定子字符串的索引
            int n=fileName.lastIndexOf(".");
            String folderName = fileName.substring(0,n);
            System.out.println(n);
            File folder = new File(folderName);
           // boolean mkdir() 创建此抽象路径名指定的目录 ,本例为f:\new
            folder.mkdir(); //创建子目录(路径)
            
            System.out.println(folderName);
            BufferedOutputStream dest = null;
            FileInputStream fis = new FileInputStream(file);
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
            //ZipEntry类用于表示 ZIP 文件条目
            ZipEntry entry;
           
           // getNextEntry() 读取下一个 ZIP 文件条目并将流定位到该条目数据的开始处
            while((entry = zis.getNextEntry()) != null) {
              if (entry.isDirectory()) continue;
                System.out.println("Extracting: " +entry);
                int count;
                byte data[] = new byte[BUFFER];
                /*write the files to the disk
                FileOutputStream(String name)
                创建一个向具有指定名称的文件中写入数据的输出文件流。
                 */
    //            String subDirName=folderName + "\\" + new File(entry.getName()).getParent();
    //            System.out.println(entry.getName());
    //            File subDir = new File(subDirName);
    //            System.out.println(subDir.getAbsolutePath());
    //            subDir.mkdirs();  
    //            
                File f1 = new File(entry.getName());
                if (f1.getParent()!=null){
                    String subDirName=folderName + "\\" + f1.getParent();
                    File subDir = new File(subDirName);
                    System.out.println(subDir.getAbsolutePath());
                    subDir.mkdirs();
                }
                
                FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry.getName());
                /*BufferedOutputStream(OutputStream out, int size)
                创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的基础输出流。
                 */
                dest = new BufferedOutputStream(fos, BUFFER);
                while ((count = zis.read(data, 0, BUFFER)) != -1) {
                    dest.write(data, 0, count);
                }
                //刷新此缓冲的输出流。
                dest.flush();
                dest.close();
            }
            zis.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    }我的问题:1) //lastIndexOf(String str)返回在此字符串中最右边出现的指定子字符串的索引
            int n=fileName.lastIndexOf(".");
    请问上句话中的此字符串是指的是"."吗?最右边指定的子字符串又指的是什么?为什么n的结果是6?
    2)我从程序的输出结果看
    entry是指 html/about.html
    entry.getName() 也是指html/about.html
    为什么entry和entry的名称是一样的呢?
    既然一样我把这句话改了:
    FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry.getName());
    我改成
    FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry);
    我测试过这样也对!
    请问到底是怎么回事??
      

  13.   

    可以查看api里的解释,其实,我也是从api里查的。1:int n=fileName.lastIndexOf("."); 
    引号里的字符串是"."(小数点),从字符串(这里是fileName)右边开始找子串".",并返回它所在的位置。如:"html/about.html".lastIndexOf(".")返回102:FileOutputStream fos = new FileOutputStream(folderName + "\\" + entry);
    我认为,你这样写,可能是因为要与字符串连接而调用了entry.toString(),从api可以看出,ZipEntry类重写了toString方法,该类的源码里是这样的:
    public String toString() {
    return getName();
        }
    可见toString()就是getName()。我觉得,写成entry.getName()会明确一些,增加可读性。
      

  14.   


    我写的压缩的程序也有些问题的:程序清单如下:package com.javaftp;
    import java.io.*;import java.util.zip.*;
    public class Zip { 
    public static void main(String[] args) {   
    try {           
    FileOutputStream f = new FileOutputStream("f:\\110.zip");      
     ZipOutputStream out = new ZipOutputStream(new DataOutputStream(f));      
    for (int i = 0; i < args.length; i++) {   
    System.out.println("Writing file " + args[i]);   
    DataInputStream in = new DataInputStream(new FileInputStream(args[i])); 
    out.putNextEntry(new ZipEntry(args[i])); 
    int c;              
    while ((c = in.read()) != -1)   
    out.write(c);             
     in.close();           
      }           
    out.close();     
    } catch (Exception e) {       
    e.printStackTrace();      
    }    
    }
    }我测试如下:
    java com\javaftp\Zip.javajava com.javaftp.Zip e:\html\*.* 这时是正常的
    但是我要把html 文件夹下在放一个new子文件夹的时候,就报e:\html\new拒绝访问了!
    我要想把我html文件夹压缩该怎么办呢?我看到上面的帖子有人说用递归做?大哥能不能把压缩的程序清单也写一下啊!谢谢了!
      

  15.   

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipOutputStream;/**
     *
     * @author Trumplet
     */
    public class ZIP {
        public static void ZipFile(File fileToZip, ZipOutputStream zos){
            try {
                String path = fileToZip.getPath();
                if (path.charAt(1)==':') path = path.substring(3);
                zos.putNextEntry(new ZipEntry(path));
                FileInputStream fis = new FileInputStream(fileToZip);
                int c;
                while ((c = fis.read()) != -1)
                    zos.write(c);
                fis.close();
                zos.closeEntry();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            
        }
        public static void findSubFiles(String start,ZipOutputStream zos){
            System.out.println(start);
            File fileStart = new File(start);
            if (fileStart.isFile()) {
                ZipFile(fileStart,zos);
                return;
            }
            String[] subFn = fileStart.list();
            for (int i=0;i<subFn.length;i++){
                File subFile = new File(start + "\\" + subFn[i]);
                if (subFile.isFile()){
                    ZipFile(subFile,zos);
                    System.out.println(subFile.getName());
                } else
                    findSubFiles(start + "\\" + subFile.getName(),zos);
            }
        }
        
        public static void main(String[] args) {
            try {
                //String[] folders = args;
                String[] folders = {"d:\\1111"};
                FileOutputStream fos = new FileOutputStream("d:\\110.zip");
                ZipOutputStream zos = new ZipOutputStream(fos);
                for (int i = 0; i < folders.length; i++) {
                    System.out.println("Writing file " + folders[i]);
                    findSubFiles(folders[i],zos);
                }
                zos.close();
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
      

  16.   

    trumplet(检查) 大哥,您好象没用递归一样做出来了啊!大哥真是高手啊!大哥能不能把压缩的程序加上注解啊,我得好好研究一下!谢谢拉!
      

  17.   

    用递归了,findSubFiles()就是递归方法。
      

  18.   

    public static void findSubFiles(String start,ZipOutputStream zos){
            System.out.println(start);
            File fileStart = new File(start);
            //要压缩的(zos),如果是一个文件,调用ZipFile压缩之,然后返回
            if (fileStart.isFile()) {
                ZipFile(fileStart,zos);
                return;
            }
            //如果不是文件,就是子目录,执行下面的操作
            String[] subFn = fileStart.list(); //取出该子目录下的文件名和子目录名
            // 下面的 for 处理这些文件或子目录
            for (int i=0;i<subFn.length;i++){
                File subFile = new File(start + "\\" + subFn[i]);
                if (subFile.isFile()){ //如果是一个文件,调用ZipFile压缩之
                    ZipFile(subFile,zos);
                    System.out.println(subFile.getName());
                } else //不是文件,就是子目录,递归之,再找。
                    findSubFiles(start + "\\" + subFile.getName(),zos);
            }
        }
      

  19.   

    //要压缩的( start ),如果是一个文件,调用ZipFile压缩之,然后返回
      

  20.   

    trumplet(检查)大哥,如果我要用JUnit编写测试程序,来对我写的程序进行测试,测试程序该怎么写呢?
      

  21.   

    没关系拉!我看书上说从文件输入. 输出流中读写数据有两种方式 ,我们用的是第一种方式就是直接利用 FileInputStream  和 FileOutputStream 自身的读写功能;第二种是 以 FileInputStream  和 FileOutputStream 为原始数据源 ,在套接上其它功能较强大的输入,输出流完成文件的读写操作.为了能更方便地从文件中读写不同类型的数据,一般用第二种方式,常用的是用过滤流的两个子类 DataInputStream和DataOutputStream ,trumplet(检查) 大哥,是不是如此??
      

  22.   

    trumplet(检查) 大哥,那你做白盒测试一般用什么呢?
      

  23.   

    谁能用JUnit对我的压缩解压程序编个测试程序呢?
      

  24.   

    trumplet(检查) 大哥,您对xml技术熟悉吗?我有个很疑惑的问题,我贴子发到Web Services / XML 里了,名字叫" 急!!计算xml文档的结点数时怎样忽略掉空白结点???在线等!! ",您可以去看下!谢拉!!