解答例 - j2.lesson09.ZipUncompressor

package j2.lesson09;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * 課題2204 - 解答例.
 * ZIPファイルからデータを取り出すプログラム.
 @author arakawa
 @version $Id: ZipUncompressor_java.rps,v 1.1 2006/03/06 12:56:15 java2005 Exp $
 */
public class ZipUncompressor {

    /**
     * ZIPファイルからデータを取り出すプログラム.
     @param args 無視される
     @throws IOException 入出力中に例外が発生した場合
     */
    // プログラム全体
    public static void main(String[] argsthrows IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        
        // print "ZIP書庫ファイル名を入力:"
        System.out.print("ZIP書庫ファイル名を入力:");
        // zip = コンソール入力 (String)
        String zip = reader.readLine();
        ZipFile zipf;
        try {
            zipf = new ZipFile(zip);
        }
        // if zip が指すファイルを読み込めない
        catch (IOException e) {
            // print zip + "が読み込めません", 改行
            System.out.println(zip + "が読み込めません");
            // return
            return;
        }
        
        try {
            // print "書庫内のファイル名を入力:"
            System.out.print("書庫内のファイル名を入力:");
            // contents = コンソール入力 (String)
            String contents = reader.readLine();
            ZipEntry entry = zipf.getEntry(contents);
            // if zip が指すファイル内に contents が存在しない
            if (entry == null) {
                // print zip + "内の" + contents + "が存在しません", 改行
                System.out.println(zip + "内の" + contents + "が存在しません");
                // return
                return;
            }

            // print "解凍先のファイル名を入力:"
            System.out.print("解凍先のファイル名を入力:");
            // target = コンソール入力
            String target = reader.readLine();
            
            try {
                // zip が指すファイル内の contents の内容を target に書き出す
                InputStream in = zipf.getInputStream(entry);
                streamCopy(in, target);
                // if 読み書き中に例外が発生しなかった
                // print target + "にコピーしました", 改行
                System.out.println(target + "にコピーしました");
            }
            // else
            catch (IOException e) {
                // print "コピー中に例外が発生しました", 改行
                System.out.println("コピー中に例外が発生しました");
            }
        }
        finally {
            zipf.close();
        }
    }
    
    /**
     * 指定したストリームの内容を指定したファイルに保存する。
     * 入力ストリームは、このメソッド終了後にクローズされる。
     @param in 書き込み元のストリーム
     @param target 書き込み先のファイル
     @throws IOException 入出力時に例外が発生した場合
     */
    private static void streamCopy(InputStream in, String targetthrows IOException {
        try {
            OutputStream out = new BufferedOutputStream(new FileOutputStream(target));
            try {
                while (true) {
                    int b = in.read();
                    if (b == -1) {
                        break;
                    }
                    out.write(b);
                }
            }
            finally {
                out.close();
            }
        }
        finally {
            in.close();
        }
    }
}