- NIOファイルシステムプロバイダを使ってカスタムファイルシステム、ZIPファイルシステムをデプロイする方法を紹介する
- NIO2ファイルシステムAPIを使ってZip/Jarファイルに簡単にアクセスできることをご紹介する
http://download.java.net/jdk7/docs/api/index.html?java/nio/file/package-summary.html
.ZIP File Format Specification
http://www.pkware.com/documents/casestudies/APPNOTE.TXT
将来のjava.util.zip.ZipFileクラスのアップデートのために用意されたコードをたまたま持っていたので、NIO2ファイルシステムプロバイダSPIでラップしてzipfs.jarとして固め、<JDK>/demo/nio/zipfsディレクトリに配置しました。
すべてのソースコードは、<JDK7>/demo/nio/zipfs/src.zip で確認できますが、簡単に確認するなら、こちらからも確認できます。
次に2個目の目的のために、サンプルコードを用意しました。FILE_NAMEというZipファイルからSRC_NAMEを取り出すには以下のようにします。
try (FileSystem fs = FileSystems.newFileSystem(Paths.get(FILE_NAME), null)) {
Files.copy(fs.getPath(SRC_NAME), Paths.get(DST_NAME);
}
もしくはZIPファイル上で"fancy nio2 walk"をするのならこんな感じ。
try (FileSystem fs = FileSystems.newFileSystem(Paths.get(FILE_NAME), null)) {java.util.zipでできなかったこんなこともできます。例えば、作成時間と最終アクセス時間を持ったZipファイルにファイルをコピーします。
Files.walkFileTree(fs.getPath(DIR_NAME), new SimpleFileVisitor<Path>() {
private int indent = 0;
private void perform(Path file, BasicFileAttributes attrs) {
if (attrs.isDirectory())
System.out.printf("%" + (indent==0?"":indent<<1) + "s[%s]%n", "", file.toString());
else
System.out.printf("%" + (indent==0?"":indent<<1) + "s%s%n", "", file.getFileName().toString());
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
perform(file, attrs);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
perform(dir, attrs);
indent += 2;
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException ioe) {
indent -= 2;
return FileVisitResult.CONTINUE;
}
}
);
}
Files.copy(Paths.get(SRC), fs.getPath(DST), COPY_ATTRIBUTES);以下は上記のコードでDemo.javaをZipファイルにコピーした結果の出力サンプルです。
/Demo.javaもっとクールなNIO/ZIPファイルシステムの利用方法はこちらでご覧頂けます。
creationTime : Fri Apr 29 22:41:46 PDT 2011
lastAccessTime : Wed May 25 20:58:36 PDT 2011
lastModifiedTime: Fri Apr 29 22:41:46 PDT 2011
isRegularFile : true
isDirectory : false
isSymbolicLink : false
isOther : false
fileKey : null
size : 26680
compressedSize : 4941
crc : c5f6eb5a
method : 8
<JDK7_HOME>/demo/nio/zipfs/Demo.java
ちゃんと動くようにするためには、<JDK>/demo/nio/zipfs/zipfs.jarをクラスパスに追加するか、lib/extディレクトリにzip.jarを追加する必要がありますが、JDK7/b123以後では、zipfs.jarはlib/extに追加されていますので、通常のファイルシステムのようにアクセスすることができます。
JDK7では、ZIPファイルシステムプロバイダはjava.net.JarURLConnectionで定めている従来のJAR URLをサポートしています。つまり、zip/JARファイルシステムは次のURIによって識別することができます。
jar:{uri}!/{entry}さらに、ZIPファイルシステムは次のURIを使って作成できます。
jar:{uri}最新のURL RFEと、従来のJAR URL構文の混在は開発者の混乱を招く可能性があるので、最新のURL RFEは取り扱わないことにしました。
JDK7では、zip/JARファイルはファイルシステム上になければならないので、URIスキーム"{uri}"にfileが入ります。例えば、
jar:file:/tmp/foo.jar新しいFileSystemを作成すると、ファイルシステムを設定するためにプロパティを使うことがあります。これらのプロパティはjava.util.Mapを介してFileSystems.newFileSystemメソッドで指定します。
jar:file:/tmp/foo.jar!/bar
キーはプロパティ名(String)と値はプロパティ値です。新しく2個のプロパティをサポートします。
create: java.lang.String型、デフォルト値は"false"。"true"の場合(大文字小文字を認識します)、zipやJARファイルが存在しない場合に作成されます。
encoding: java.lang.String型、デフォルト値は"UTF-8"。Zipファイル、JARファイル中のエントリのエンコード名を示します。近くにZipファイルやJarファイルがあれば試して見てください。そして改善点があればお知らせください。
原文はこちら。
http://blogs.oracle.com/xuemingshen/entry/the_zip_filesystem_provider_in1
0 件のコメント:
コメントを投稿