<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 117  文章 - 72  trackbacks - 0

    聲明:原創作品(標有[原]字樣)轉載時請注明出處,謝謝。

    常用鏈接

    常用設置
    常用軟件
    常用命令
     

    訂閱

    訂閱

    留言簿(7)

    隨筆分類(130)

    隨筆檔案(123)

    搜索

    •  

    積分與排名

    • 積分 - 155536
    • 排名 - 390

    最新評論

    [關鍵詞]:ant,zip,unzip,Apache,壓縮,解壓,中文亂碼,ZipEntry
         先前寫了一篇blog《使用org.apache.tools.zip實現zip壓縮和解壓》,現對它進行了改進:找出了幾個Bug,修改了部分代碼,增加了注釋,添加了圖形界面,打了個可執行包,雙就可以運行了。源代碼如下,希望大家多提意見。

    MyZip.java:
    package myzip;
    import java.io.*;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import myzip.AntZip;

    /**
     *界面類,調用AntZip類實現壓縮解壓功能。
     *@version 2009-3-18
     *@author Winty (wintys@gmail.com)
     */
    public class MyZip{
        public static void main(String[] args){
            new MyZip(new AntZip());
        }

        public MyZip(AntZip zip){
            this.zip = zip;
            this.latestDir = new File(".");
            buildUI();       
        }

        public void buildUI(){
            jframe = new JFrame();
            jframe.setTitle("MyZip");
            jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jframe.setResizable(false);
            jframe.setSize(230 , 150);
            Dimension screen= Toolkit.getDefaultToolkit().getScreenSize();
            jframe.setLocation((screen.width-jframe.getWidth())/2,
                                         (screen.height-jframe.getWidth())/2);

            jframe.setLayout(null);
            Container contentPane = jframe.getContentPane();

            JButton zipBtn;
            JButton unzipBtn;
            zipBtn = new JButton("壓縮");
            unzipBtn = new JButton("解壓");
            zipBtn.setSize(60 , 40);
            unzipBtn.setSize(60 , 40);
            zipBtn.setLocation(40,40);
            unzipBtn.setLocation(120 , 40);
            contentPane.add(zipBtn);
            contentPane.add(unzipBtn);

            zipBtn.addActionListener(new ActionHandler());
            unzipBtn.addActionListener(new ActionHandler());

            jframe.setVisible(true);
        }

        private JFrame jframe;
        private AntZip zip;
        private File latestDir;/*記錄最近使用的文件夾路徑*/

        /*內部類監聽器*/
        class ActionHandler implements ActionListener{
            public void actionPerformed(ActionEvent event){
                JFileChooser chooser = new JFileChooser();
                chooser.setCurrentDirectory(latestDir);

                String cmd = event.getActionCommand();
                if(cmd.equals("壓縮")){
                    chooser.setFileSelectionMode(
                        JFileChooser.FILES_AND_DIRECTORIES);
                    chooser.setMultiSelectionEnabled(true);

                    int returnVal = chooser.showOpenDialog(jframe);
                    if(returnVal == JFileChooser.APPROVE_OPTION) {
                        File[] files = chooser.getSelectedFiles();
                        if(files!=null){
                            zip.doZip(files , files[0].getName());
                            latestDir = files[0].getParentFile();
                        }
                    }
                }
                else if(cmd.equals("解壓")){
                    chooser.setMultiSelectionEnabled(false) ;

                    int returnVal = chooser.showOpenDialog(jframe);
                    if(returnVal == JFileChooser.APPROVE_OPTION) {
                        File file = chooser.getSelectedFile();
                        if(file!=null){
                            zip.unZip(file);
                            latestDir = file.getParentFile();
                        }
                    }
                }

            }
        }
    }

    AntZip.java:
    package myzip;
    import java.io.*;
    import org.apache.tools.zip.*;
    import java.util.Enumeration;
    /**
    *功能:zip壓縮、解壓(支持中文文件名)
    *說明:使用Apache Ant提供的zip工具org.apache.tools.zip實現zip壓縮和解壓功能.
    *   解決了由于java.util.zip包不支持漢字的問題。
    *   使用java.util.zip包時,當zip文件中有名字為中文的文件時,
    *   就會出現異常:
    *        "Exception  in thread "main " java.lang.IllegalArgumentException
    *      at   java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:285)
    *
    *注意:
    *   1、使用時把ant.jar放到classpath中,程序中使用import org.apache.tools.zip.*;
    *   2、Apache Ant 下載地址:http://ant.apache.org/
    *   3、Ant ZIP Online API:
    *www.jajakarta.org/ant/ant-1.6.1/docs/mix/manual/api/org/apache/tools/zip/
    *   4、本程序使用Ant 1.7.1 中的ant.jar。
    *   5、如果只需要Ant的zip壓縮功能,不需要Ant的其它功能,
    *     那么可以減小ant.jar的大小。方法是用WinRAR打開ant.jar,
    *     把沒有用到的包和class文件都刪除。這樣ant.jar體積就減小了。
    *   6、ZipEntry的isDirectory()方法中,目錄以"/"結尾。
    *
    *僅供編程學習參考.
    *
    *Copyright (c) Winty
    *http://www.tkk7.com/wintys
    *
    *@author Winty (wintys@gmail.com)
    *@version   2008-8-3
    *------------------------------------------------
    *可將主函數注釋去掉以單獨測試AntZip類。
    *Compile:
    *   javac -cp Ant.jar AntZip.java
    *
    *Usage:(將ant.jar直接放在當前目錄)
    *   壓縮:java -cp Ant.jar;.  AntZip -zip [directoryName | fileName]...
    *   解壓:java -cp Ant.jar;.  AntZip -unzip "fileName.zip"
    *
    *------------------------------------------------
    *2009-3-17:
    *修正一處Bug,當解壓的zip文件中根目錄下直接有文件時會出錯。
    *將unZip()中的if(!parent.exists())改正為:if(parent!=null && !parent.exists())
    *
    *2009-3-18:
    *多處其它修改
    *------------------------------------------------
    */

    public class AntZip{
        private ZipFile         zipFile;
        private ZipOutputStream zipOut;     //壓縮Zip
        private ZipEntry        zipEntry;
        private static int      bufSize;    //size of bytes
        private byte[]          buf;
        private int             readedBytes;
        //用于壓縮中。要去除的絕對父路路徑,目的是將絕對路徑變成相對路徑。
        private String deleteAbsoluteParent;
       
        /**
         *構造方法。默認緩沖區大小為512字節。
         */
        public AntZip(){
            this(512);
        }

        /**
         *構造方法。
         *@param bufSize 指定壓縮或解壓時的緩沖區大小
         */
        public AntZip(int bufSize){
            this.bufSize = bufSize;
            this.buf = new byte[this.bufSize];
            deleteAbsoluteParent = null;
        }
       
        /**
         *壓縮文件夾內的所有文件和目錄。
         *@param zipDirectory 需要壓縮的文件夾名
         */
        public void doZip(String zipDirectory){
            File zipDir = new File(zipDirectory);
            doZip(new File[]{zipDir} , zipDir.getName());
        }

        /**
         *壓縮多個文件或目錄。可以指定多個單獨的文件或目錄。而
         *<code>doZip(String zipDirectory)</code>則直接壓縮整個文件夾。
         *@param files 要壓縮的文件或目錄組成的<code>File</code>數組。
         *@param zipFileName 壓縮后的zip文件名,如果后綴不是".zip",
         *  自動添加后綴".zip"。
         */
        public void doZip(File[] files , String zipFileName){
            //未指定壓縮文件名,默認為"ZipFile"
            if(zipFileName==null || zipFileName.equals(""))
                zipFileName = "ZipFile";

            //添加".zip"后綴
            if(!zipFileName.endsWith(".zip"))
                zipFileName += ".zip";

            try{
                this.zipOut = new ZipOutputStream(
                    new BufferedOutputStream(new FileOutputStream(zipFileName)));
                compressFiles(files , this.zipOut , true );
                this.zipOut.close();
            }catch(IOException ioe){
                ioe.printStackTrace();
            }
        }

        /**
         *壓縮文件和目錄。由doZip()調用
         *@param files 要壓縮的文件
         *@param zipOut zip輸出流
         *@param isAbsolute 是否是要去除的絕對路徑的根路徑。因為compressFiles()
         *會遞歸地被調用,所以只用deleteAbsoluteParent不行。必須用isAbsolute來指明
         *compressFiles()是第一次調用,而不是后續的遞歸調用。即如果要壓縮的路徑是
         *E:\temp,那么第一次調用時,isAbsolute=true,則deleteAbsoluteParent會記錄
         *要刪除的路徑就是E:\ ,當壓縮子目錄E:\temp\folder時,isAbsolute=false,
         *再遞歸調用compressFiles()時,deleteAbsoluteParent仍然是E:\ 。從而保證了
         *將E:\temp及其子目錄均正確地轉化為相對目錄。這樣壓縮才不會出錯。不然絕對
         *路徑E:\也會被寫入到壓縮文件中去。
         */
        private void compressFiles(File[] files ,
                                                ZipOutputStream zipOut ,
                                                boolean isAbsolute) throws IOException{

            for(File file : files){
                if(file==null)continue; //空的文件對象

                //刪除絕對父路徑
                if(file.isAbsolute()){
                    if(isAbsolute){
                        deleteAbsoluteParent = file.getParentFile().getAbsolutePath();
                        deleteAbsoluteParent = appendSeparator(deleteAbsoluteParent);
                    }
                }
                else
                    deleteAbsoluteParent = "";

                if(file.isDirectory()){//是目錄
                    compressFolder(file , zipOut);
                }
                else{//是文件
                    compressFile(file , zipOut);
                }
            }
        }

        /**
         *壓縮文件或空目錄。由compressFiles()調用。
         *@param file 需要壓縮的文件
         *@param zipOut zip輸出流
         */
        public void compressFile(File file , ZipOutputStream zipOut)
            throws IOException{

            String fileName = file.toString();

            /*去除絕對父路徑。*/
            if(file.isAbsolute())
                fileName = fileName.substring(deleteAbsoluteParent.length());
            if(fileName == null || fileName=="")
                return;


            /*因為是空目錄,所以要在結尾加一個"/"。
              不然就會被當作是空文件。
              ZipEntry的isDirectory()方法中,目錄以"/"結尾.
              org.apache.tools.zip.ZipEntry :
                public boolean isDirectory() {
                    return getName().endsWith("/");
                }
              */
            if(file.isDirectory())
                fileName = fileName + "/";//此處不能用"\\"

            zipOut.putNextEntry(new ZipEntry(fileName));

            //如果是文件則需讀;如果是空目錄則無需讀,直接轉到zipOut.closeEntry()。
            if(file.isFile()){
                FileInputStream fileIn = new FileInputStream(file);
                while((this.readedBytes = fileIn.read(this.buf))>0){
                    zipOut.write(this.buf , 0 , this.readedBytes);
                }
                fileIn.close();
            }

            zipOut.closeEntry();
        }

        /**
         *遞歸完成目錄文件讀取。由compressFiles()調用。
         *@param dir 需要處理的文件對象
         *@param zipOut zip輸出流
         */
        private void compressFolder(File dir , ZipOutputStream zipOut)
            throws IOException{
           
            File[] files = dir.listFiles();
       
            if(files.length == 0)//如果目錄為空,則單獨壓縮空目錄。
                compressFile(dir , zipOut);
            else//如果目錄不為空,則分別處理目錄和文件.
                compressFiles(files , zipOut , false);
        }
       
        /**
         *解壓指定zip文件。
         *@param unZipFileName 需要解壓的zip文件名
         */
        public void unZip(String unZipFileName){
            FileOutputStream fileOut;
            File file;
            InputStream inputStream;

            try{
                this.zipFile = new ZipFile(unZipFileName);

                for(Enumeration entries = this.zipFile.getEntries();
                    entries.hasMoreElements(); ){

                    ZipEntry entry = (ZipEntry)entries.nextElement();
                    file = new File(entry.getName());

                    if(entry.isDirectory()){//是目錄,則創建之
                        file.mkdirs();
                    }
                    else{//是文件
                        //如果指定文件的父目錄不存在,則創建之.
                        File parent = file.getParentFile();
                        if(parent!=null && !parent.exists()){
                            parent.mkdirs();
                        }

                        inputStream = zipFile.getInputStream(entry);

                        fileOut = new FileOutputStream(file);
                        while(( this.readedBytes = inputStream.read(this.buf) ) > 0){
                            fileOut.write(this.buf , 0 , this.readedBytes );
                        }
                        fileOut.close();

                        inputStream.close();
                    }  
                }
                this.zipFile.close();
            }catch(IOException ioe){
                ioe.printStackTrace();
            }
        }

       
        /**
         *給文件路徑或目錄結尾添加File.separator
         *@param fileName 需要添加路徑分割符的路徑
         *@return 如果路徑已經有分割符,則原樣返回,否則添加分割符后返回。
         */
        private String appendSeparator(String path){
            if(!path.endsWith(File.separator))
                            path += File.separator;
            return path;
        }

        /**
         *解壓指定zip文件。
         *@param unZipFile 需要解壓的zip文件對象
         */
        public void unZip(File unZipFile){
            unZip(unZipFile.toString());
        }

        /**
         *設置壓縮或解壓時緩沖區大小。
         *@param bufSize 緩沖區大小
         */
        public void setBufSize(int bufSize){
            this.bufSize = bufSize;
        }

        //主函數,用于測試AntZip類
        /*
        public static void main(String[] args)throws Exception{
            if(args.length>=2){
                AntZip zip = new AntZip();

                if(args[0].equals("-zip")){
                    //將后續參數全部轉化為File對象
                    File[] files = new File[ args.length - 1];
                    for(int i = 0;i < args.length - 1; i++){
                        files[i] = new File(args[i + 1]);
                    }

                    //將第一個文件名作為zip文件名
                    zip.doZip(files , files[0].getName());

                    return ;
                }
                else if(args[0].equals("-unzip")){
                    zip.unZip(args[1]);
                    return ;
                }
            }
           
            System.out.println("Usage:");
            System.out.println("壓縮:java AntZip -zip [directoryName | fileName]... ");
            System.out.println("解壓:java AntZip -unzip fileName.zip");
        }
        */
    }

    附件內容:
    /MyZip.jar : 打包后的可執行文件,可單獨運行,內含org.apache.tools.zip包。運行環境JRE1.6+
    /使用Ant實現zip壓縮解壓功能/ant.jar : 精簡后的ant包,只包含org.apache.tools.zip
    /使用Ant實現zip壓縮解壓功能/AntZip.java
    /使用Ant實現zip壓縮解壓功能/MyZip.java

    [附件]:使用Ant實現zip壓縮解壓功能.zip
    posted on 2009-03-19 13:17 天堂露珠 閱讀(4765) 評論(11)  編輯  收藏 所屬分類: Java

    FeedBack:
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-11 16:23 豬影橫飛
    你好,學習了你的ANT實現ZIP壓縮技術,受益匪淺,想問下,如果我想做成壓縮雙機文件通信(即采用服務端/客戶端形式),點擊發送端按鈕->選擇文件->壓縮成*.zip文件->發送給客戶端,點擊接收端按鈕->選擇保存路徑->接收*.zip文件->解壓*.zip文件,請問如何實現和調用?
    hszcy521@163.com  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-11 20:17 天堂露珠
    那就需要用到TCP或UDP通信了,參見我的CSDN文章:《Java UDP網絡編程 - 最簡單示例》:http://blog.csdn.net/wintys/archive/2008/12/15/3525643.aspx ,以及《Java TCP網絡編程 - 最簡單示例》:http://blog.csdn.net/wintys/archive/2008/12/15/3525619.aspx 。  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-11 21:56 豬影橫飛
    恩,這個我會寫已經寫好了SERVER.JAVA和CLIENT.JAVA了,但里邊都帶有main函數,在JDK編程的環境下能直接運行,我想問的就是如何再GUI.JAVA里的事件處理中按我的流程調用?服務端先壓縮再傳送,客戶端先接收再解壓  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-11 23:16 天堂露珠
    @豬影橫飛
    兩個客戶端都一直在監聽著指定的端口,用線程實現監聽。
    以下僅為示意性代碼:

    1、發送
    比如就用我寫的MyZip.java的界面,把"壓縮"改成"發送",
    if(cmd.equals("壓縮")){
    ......
    if(files!=null){
    //先壓縮所選文件夾內的文件,結果會生成一個zip文件,假設為"file.zip"
    zip.doZip(files , files[0].getName());
    latestDir = files[0].getParentFile();

    //udp為UDP通信類。
    //獲取"file.zip"的字節數組,啟動一個線程,
    //把它當作一個或多個數據包發送出去,
    //而此時,另一個客戶端正在監聽著,它收到數據后,進行相反的操作。
    udp.send(filePacket);
    }
    ......
    }


    2、接收
    也就是說,沒有數據發送的時候,兩個客戶端都有一個后臺線程運行著:
    class Client implements Runnable{
    public void run(){
    while(true){
    //接收,沒有收到時,將一直等待
    datagramSocket.receive(recvPacket);
    //解壓
    Unzip();
    }
    }
    }  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-12 22:36 豬影橫飛
    @天堂露珠
    謝謝你的指點,非常感謝!~  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-13 21:07 王琦均
    如果是要求以流的形式傳入zip文件,那怎么解決呢
    我看了ant里面好像沒有提供這樣的方法。
    里面 沒有zipInputStream 只有zipOutputStream

    我這里提的方法就是:
    //這里的流就是出入的zip文件流
    public int getText(InputStream is){

    }  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-13 22:34 天堂露珠
    @王琦均
    只有自己獨立解決問題,才可能真正成長,不能每一步都問吧。
    其實我的程序中已經用到了,org.apache.tools.zip.ZipFile.getInputStream(ZipEntry ze)就是輸入流。  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-14 01:20 王琦均
    @天堂露珠
    外部只調我這個程序的這個方法哦
    也就是外部程序只給我傳個流進來。  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-14 01:23 王琦均
    @天堂露珠
    外部是不會用org.apache.tools.zip.ZipFile.getInputStream(ZipEntry ze)
    來給你轉化的。
    直接就是個文件流傳進來的!  回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-29 15:41 shappy
    @王琦均 可能我的答案是你想要的,你是希望直接輸出zip流,而不是zip文件嗎
    //創建zip流
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ZipOutputStream zout = new ZipOutputStream(out);
    //省略
    ByteArrayInputStream zin= new ByteArrayInputStream(out.toByteArray());
    byte[] aryRead = new byte[zin.available()];
    //有inputstream,也有byte[]

      回復  更多評論
      
    # re: [原]使用Ant實現zip壓縮解壓功能 2009-06-29 15:51 shappy
    //創建zip流
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ZipOutputStream zout = new ZipOutputStream(out);
    //省略壓縮代碼
    zout.close(); //很奇怪,這里如果不關閉的話,檢測到輸出的流稍小一點,而且數據也有一些差異,誰能解釋一下
    ByteArrayInputStream zin= new ByteArrayInputStream(out.toByteArray());
    byte[] aryRead = new byte[zin.available()];
    //有inputstream,也有byte[]   回復  更多評論
      
    主站蜘蛛池模板: 亚洲性日韩精品一区二区三区| 亚洲欧洲日产国码av系列天堂 | 国产一精品一AV一免费孕妇 | 亚洲色成人四虎在线观看| 在线观看永久免费视频网站| 中文字幕av免费专区| 亚洲成无码人在线观看| 亚洲第一黄色网址| 24小时免费看片| 免费一区二区三区在线视频| 777亚洲精品乱码久久久久久| 成人毛片18女人毛片免费| 国产真人无码作爱免费视频| 亚洲91精品麻豆国产系列在线| 亚洲国产日韩在线观频| 91精品国产免费久久国语麻豆| 精品久久久久久亚洲中文字幕| 亚洲国产香蕉碰碰人人| 四虎免费久久影院| 亚洲免费在线观看视频| 免费人成视频在线播放| 亚洲av无码国产综合专区 | 亚洲精品国产手机| 久久亚洲av无码精品浪潮| 国产在线a免费观看| 成人电影在线免费观看| 国产精品亚洲片在线花蝴蝶| 亚洲人成电影亚洲人成9999网 | 久久青青草原亚洲AV无码麻豆 | 亚洲熟妇无码久久精品| 亚洲美女又黄又爽在线观看| 日韩中文字幕在线免费观看| 亚洲免费人成视频观看| 免费精品一区二区三区第35| 无遮挡a级毛片免费看| 日韩亚洲产在线观看| 亚洲精品日韩专区silk| 亚洲综合精品香蕉久久网| 国产免费久久精品| 成人免费视频一区| h视频在线观看免费完整版|