java.util.zip.ZipOutputStream

目的
Zipファイルの圧縮プログラムの作成

関連クラス

今回のソース
//////////////////// Main.java ////////////////////

class Main
{
	public static void main(String args[])
	{
		new ZipDeflator(args);
	}
}

////////////////////////////////////////////////////////////

//////////////////// ZipDeflator.java ////////////////////

import java.util.zip.*;
import java.io.*;

class ZipDeflator
{
	public ZipDeflator(String files[])
	{
		try
		{
			String archive_name = files[0];
			ZipOutputStream output = new ZipOutputStream(new FileOutputStream(archive_name));
			output.setMethod(ZipOutputStream.DEFLATED);

			for(int i=1; i<files.length; i++)
			{
				byte[] data = getDataFromFile(files[i]);
				ZipEntry zip_entry = new ZipEntry(files[i]);

				System.out.println("File: " + files[i]);
				System.out.print("Deflating...");

				output.putNextEntry(zip_entry);
				output.write(data, 0, data.length);
				output.closeEntry();

				System.out.println("Done!");
				System.out.println("");
			}

			output.close();
		}
		catch(IOException e)
		{
			System.err.println(e);
			System.exit(1);
		}
	}

	// ファイル中のデータをbyte配列にして返す
	public byte[] getDataFromFile(String file_name)
	{
		try
		{
			File file = new File(file_name);
			int file_length = (int)file.length();

			FileInputStream file_in = new FileInputStream(file);
			byte data[] = new byte[file_length];

			int read_bytes, offset = 0;
			while((read_bytes = file_in.read(data, offset, file_length)) != -1)
			{
				offset += read_bytes;
				if(offset == file_length)
					break;
			}
			file_in.close();

			return(data);
		}
		catch(IOException io_ex)
		{
			System.err.println(io_ex);
			return(null);
		}
		catch(Exception e)
		{
			System.err.println(e);
			return(null);
		}
	}
}

////////////////////////////////////////////////////////////
Source is here. (ZIP Format, 931Byte, Shift-JIS)

コンパイル&実行
javac Main.java
java Main <Archive Name> <Complessing Files1> <Complessing Files2> ...

説明
(概略)

ZIPの圧縮プログラムです。
簡単なプログラムなので、特に説明することも無いでしょう。

うちの環境では、WinZipでは解凍できても、
Lhasaだと、中身のファイルが全て0Byteになるという奇妙な現象が起こってます。
う〜ん。不思議だ...

(サンプルプログラムの説明)

output.setMethod(ZipOutputStream.DEFLATED);
ZipOutputStream.DEFLATEDは、圧縮を表す定数です。
これを、setMethodで指定することによって、ストリームを圧縮用にすることが出来ます。
ZipEntry zip_entry = new ZipEntry(files[i]);
ZipEntryは、アーカイブに格納するファイル一つに相当します。
ファイル名を指定することで、一つのZipEntryを作成しています。
output.putNextEntry(zip_entry);
output.write(data, 0, data.length);
output.closeEntry();
putNextEntryメソッドで、新しいZipEntryの書きこみを開始し、
closeEntryメソッドで、現在のZipEntryの書きこみを終了します。
つまり、putNextEntryで準備してから、実際のデータの書きこみを行い、
closeEntryで書きこみを終了させています。
int read_bytes, offset = 0;
while((read_bytes = file_in.read(data, offset, (file_length - offset))) != -1)
{
  offset += read_bytes;
  if(offset == file_length)
    break;
}
単に、file_in.read(data, 0, file_length); としないのは、
ファイルが大きい場合などに、一度に読みこめない可能性があるからです。
そこで、readメソッドが返す読み込むことが出来たByte数を取得し、
残っていないかどうかを確認しながら読みこむという方式を取っています。