◆PROCESSING 逆引きリファレンス
カテゴリー:ファイル操作
ZIP圧縮を行うには(zip4j編)
【概要】
PROCESSINGはJavaをベースにした言語ですので、Javaの機能を利用してZIP圧縮を行うことが可能です。
ただしJavaの標準機能(標準ライブラリ)では、パスワード付きのZIPファイルを作成することができません。また圧縮方式にZipCrypto(Zip2.0暗号方式)を採用していますが、この圧縮方式には既に脆弱性が発見されています。
パスワード付きのZIPファイルを作成する場合や、より強固な暗号化を施したZIPファイルを作成する場合に便利なのが zip4jライブラリです。
【詳細】
最新のライブラリを入手する
PROCESSINGでzip4jを使うなら、そのライブラリは Maven Repository からダウンロードするのが便利です。2020年02月現在、Version 2.3.1 が公開されています。
2.3.1なら「zip4j-2.3.1.jar」のようなファイルがダウンロードできると思いますので、なるべく新しいものを入手しておいてください。
Intellij IDEAなどのIDE経由で開発をされている人なら、GradleやMaven経由で取得すれば良いでしょう。
PROCESSINGで利用できるようにする
まずPROCESSINGの標準エディタから「新規プロジェクト」を作成し、空で良いので一度保存します。
なお保存前に「ファイル→設定」で、スケッチブックの場所に「わかりやすいパス」が指定されている事を確認してください。
上記例なら、スケッチを保存すると「D:\processing-3.5.3\src」に「sketch_190721a」などのフォルダが作成され、空のプログラムソースファイルができあがります。
このフォルダ(D:\processing-3.5.3\src\sketch_190721a)配下に、code フォルダを作成してください。
続いて、上記でダウンロードした jarファイルを、code フォルダの中に複写します。
これで準備完了です。標準エディタを開いている人は、一度PROCESSINGを終了して、標準エディタを再起動してください。
ZIPファイルを作成するには、おおまかに以下の手順で作業を行います。
- ZipParametersで圧縮方法を指定
- ZipFileインスタンスを作成
- ZipFileインスタンスに圧縮対象を追加
以下、順を追って説明します。
ZipParametersで圧縮方法を指定
zip4jを使った圧縮ファイルの作成では、パスワードなし・パスワード有りの、どちらの圧縮ファイルを作る事も可能です。
また暗号化方式に、暗号化なし、ZipCrypto(Zip2.0暗号方式)、AESを選択できます。
これらの組み合わせをZipParametersのインスタンスに対して設定し、ZipFileインスタンスにファイルを追加する際に指定します。
ZipParametersのインスタンスを作成する
インスタンスを作成ZipParameters params = new ZipParameters();
params:ZipParametersインスタンス
作成は簡単ですね。作成されたインスタンスに、必要なパラメータを指定します。
パスワード有りなしを指定する
ZipParametersクラスのsetEncryptFiles()メソッドで、パスワード有りなしを指定します。デフォルト(未指定時)はパスワードなしになります。
パスワード有無を指定void params.setEncryptFiles( boolean encryptFlg );
params:ZipParametersインスタンス
encryptFlg :パスワード有無。trueならパスワード有り
パスワード有りを指定した場合は、ZipFileインスタンスを作成する際に、引数としてパスワードを与えてください。
圧縮の有無を指定する
ZIPファイルを作成する際に圧縮するか否かを選択可能です。デフォルトは圧縮する(DEFLATE)になります。
圧縮の有無を指定void params.setCompressionMethod( CompressionMethod compression );
params:ZipParametersインスタンス
compression:圧縮の有無。CompressionMethod列挙型の定数を与える
CompressionMethod列挙型の定数には、以下のようなものがあります。
定数 | 説明 | |
---|---|---|
1 | STORE | 圧縮しない |
2 | DEFLATE | 圧縮する |
圧縮率を指定する
圧縮する場合は、圧縮率の指定が可能です。。非圧縮の場合は、意味を持ちません。デフォルトの圧縮率は普通レベル(NORMAL)です。
圧縮率を指定void params.setCompressionLevel( CompressionLevel level );
params:ZipParametersインスタンス
level:圧縮率。CompressionLevel列挙型の定数を与える
CompressionLevel列挙型の定数には、以下のようなものがあります。
定数 | 説明 | |
---|---|---|
1 | FASTEST | 最高速(最低限の圧縮率) |
2 | FAST | 高速(低圧縮) |
3 | NORMAL | 普通 |
4 | MAXIMUM | 低速(高圧縮) |
5 | ULTRA | 再低速(最高圧縮) |
圧縮率と圧縮スピードは、一般的にトレードオフの関係にあります。
またjpgやpngなど、すでに何らかの形式で圧縮されているファイルを圧縮しても、たいした効果は得られません。
暗号化方式を指定する
圧縮する場合、暗号化方式を選択可能です。圧縮しない場合は、意味を持ちません。デフォルトの暗号化方式は、ZipCrypto(ZIP_STANDARD)になります。
暗号化方式を指定void params.setEncryptionMethod( EncryptionMethod encrypt );
params:ZipParametersインスタンス
encrypt:圧縮方式。EncryptionMethod列挙型の定数を与える
EncryptionMethod列挙型の定数には、以下のようなものがあります。
定数 | 説明 | |
---|---|---|
1 | NONE | 暗号なし |
2 | ZIP_STANDARD | スタンダード方式 |
3 | ZIP_STANDARD_VARIANT_STRONG | 強化版スタンダード方式? |
4 | AES | AES |
ZIP_STANDARD_VARIANT_STRONGがどのような方式なのか、詳細不明でした。また私の環境では例外エラーとなり、そもそも使用できませんでした(汗)。
通常はZIP_STANDARDかAESを選択することになると思います。
なおsetEncryptFiles()メソッドでパスワード付きを指定した場合は、暗号化方式にNONEは選択できません。
ZIP_STANDARDよりもAESの方が強力な暗号化方式ですが、AESで圧縮されたZIPファイルは、Windowsの標準機能で解凍できなくなります。そこは注意してください。
暗号強度を指定する
暗号化方式にAESを選択した場合、setAesKeyStrength()メソッドで暗号強度を選択可能です。デフォルトはAES256(KEY_STRENGTH_256)になります。
暗号強度を指定void params.setAesKeyStrength( AesKeyStrength aesKey );
params:ZipParametersインスタンス
aesKey:圧縮強度。AesKeyStrength列挙型の定数を与える
AesKeyStrength列挙型の定数には、以下のようなものがあります。
定数 | 説明 | |
---|---|---|
1 | KEY_STRENGTH_128 | AES128 |
2 | KEY_STRENGTH_192 | AES192 |
3 | KEY_STRENGTH_256 | AES256 |
なおKEY_STRENGTH_192は、私の環境では例外エラーとなり使用することができませんでした。
一連の流れは以下のようになります。
- 圧縮あり・パスワードなし・STANDARDの例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/** * ZIP圧縮パラメータ作成処理 * 圧縮・パスワードなし・ZIP2.0形式 */ ZipParameters makeCompNonpwdStanderd(){ //パラメータ作成 ZipParameters param = new ZipParameters(); //圧縮あり param.setCompressionMethod(CompressionMethod.DEFLATE); //パスワードなし param.setEncryptFiles(false); //暗号化方式は標準形式 param.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD); //圧縮率は低圧縮(速度優先) param.setCompressionLevel(CompressionLevel.FASTEST); return param; } |
- 圧縮あり・パスワードあり・AESの例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/** * ZIP圧縮パラメータ作成処理 * 圧縮・パスワードあり・AES256形式 */ ZipParameters makeCompPwdAes(){ //パラメータ作成 ZipParameters param = new ZipParameters(); //圧縮あり param.setCompressionMethod(CompressionMethod.DEFLATE); //パスワードあり param.setEncryptFiles(true); //暗号化方式はAES param.setEncryptionMethod(EncryptionMethod.AES); //暗号強度はAES256 param.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256); //圧縮率は高圧縮(速度犠牲) param.setCompressionLevel(CompressionLevel.MAXIMUM); return param; } |
ZipFileインスタンスを作成
ZIP圧縮するには、ZipFileインスタンスを作成します。
ZipFileインスタンスを作成ZipFile zip = new ZipFile( String zipFileName );
ZipFile zip = new ZipFile( String zipFileName, char[] password );
zip:ZipFileインスタンス
zipFileName:ZIPファイル名
password:パスワード
ZipParameters のsetEncryptFiles()メソッドでパスワード有りを指定したか否かで、引数が異なります。
パスワード有りの場合は、必ず第2引数にパスワードを与えます。空文字やNULLを与えると例外エラーとなるので注意してください。
以下はパスワード付きの場合の生成例です。
1 2 3 |
//ZipFileをパスワード付きで作成する ZipFile zip = new ZipFile("c:\\temp\\fuga.zip", "password".toCharArray()); |
この例なら、生成される圧縮ファイルが 「c:¥temp¥fuga.zip」 に、パスワードが「password」になります。
文字コードを指定する
ZipFileインスタンスに、利用する文字コードの指定を行うことが可能です。デフォルトはシステムの文字コードが用いられるようです(WindowsならMS932)。
LinuxやMacの人はUTF-8などを指定すると幸せになれるかもしれませんが、圧縮したファイルの提供先がWindowsならMS932にしておくのが無難です。
文字コードを指定するvoid zip.setCharset( Charset charset );
zip:ZipFileインスタンス
charset:Charsetクラスの文字コード指定
1 2 3 4 5 6 7 8 9 |
//圧縮パラメータを作成する ZipParameters param = makeCompPwdAes(); //ZipFileをパスワード付きで作成する ZipFile zip = new ZipFile("c:\\temp\\fuga.zip", "password".toCharArray()); //利用する文字コードを指定 zip.setCharset(Charset.forName("MS932")); |
例えば上記のような感じになります。
指定可能な文字コードについては、Javaの公式ドキュメントを参照してください。
ZipFileインスタンスに圧縮対象を追加
ZipFileインスタンスを作成しただけでは、圧縮ファイルは作成されません。圧縮したいファイルもしくはフォルダを、ZipFileインスタンスに追加する事で、圧縮が行われます。
ファイルを圧縮するには.ZipFileのaddFile()メソッドを、フォルダの中身を圧縮するにはaddFolder()メソッドを利用します。
addFolder()メソッドでは、指定されたフォルダ配下にある全てのファイルとフォルダが圧縮されます。
void zip.addFiles( List filelist, ZipParameters param )
void zip.addFolder( File folder, ZipParameters param );
zip:ZipFileインスタンス
param:ZipParametersインスタンス
file:対象ファイル
filelist:対象ファイルリスト
folder:対象フォルダー
1 2 3 4 5 6 7 8 |
//圧縮対象ファイルを追加(圧縮)する File file = new File("c:\\temp\\hoge.txt"); try{ zip.addFolder(file, param); } catch( ZipException e ){ e.printStackTrace(); } |
上記例では「c:¥temp¥hoge.txt」ファイルを圧縮しています。addFiles()メソッドを利用すると、複数のファイルをリスト形式で渡すことも可能です。
【関連記事】
サンプルプログラム
ZIP圧縮を行う例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.model.enums.CompressionMethod; import net.lingala.zip4j.ZipFile; /** * PROCESSING 3 zip4j 圧縮Sample * @auther MSLABO * @version 2020/02 1.0 */ /** * ZIP圧縮パラメータ作成処理 * 圧縮・パスワードあり・AES256形式 */ ZipParameters makeCompPwdAes(){ ZipParameters param = new ZipParameters(); //圧縮あり param.setCompressionMethod(CompressionMethod.DEFLATE); //パスワードあり param.setEncryptFiles(true); //暗号化方式はAES param.setEncryptionMethod(EncryptionMethod.AES); //暗号強度はAES256 param.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256); return param; } void setup() { size(100, 100); //圧縮パラメータを作成する ZipParameters param = makeCompPwdAes(); //ZipFileをパスワード付きで作成する ZipFile zip = new ZipFile("c:\\temp\\fuga.zip", "password".toCharArray()); //圧縮対象ファイルを追加(圧縮)する ArrayList<File> filelist = new ArrayList<File>(); File file1 = new File("c:\\temp\\hoge1.txt"); filelist.add( file1 ); File file2 = new File("c:\\temp\\hoge2.txt"); filelist.add( file2 ); try{ zip.addFiles(filelist, param); } catch( ZipException e ){ e.printStackTrace(); } } void draw() { } |
c:¥tempにあるhoge1.txtとhoge2.txtを、AES256で圧縮しています。
<出力サンプル>
上記は圧縮したファイルを、フリーの圧縮解凍ソフトで見た様子です。
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。