23
nio2(JSR203)勉強会 大崎

Nio2

Embed Size (px)

Citation preview

Page 1: Nio2

nio2(JSR203)勉強会

大崎 瑶

Page 2: Nio2

nio2

• nio(JSR51)の積み残し

• 非同期I/O

• マルチキャストサポート

• ファイルシステムインタフェース

Page 3: Nio2

ファイルシステムインタフェース

Page 4: Nio2

java.nio.file.FileSystem

FileSystem fileSystem = FileSystems.getDefault();

Path path = fileSystem.getPath(“foo.txt”);

FileSystemの取得

Pathの取得

List<FileSystemProvider> providers =

FileSystemProvider.installedProviders();

FileSystemはFileSystemProviderによって提供される。一覧は、installedProviders()で取得できます。

Page 5: Nio2

ディレクトリ

DirectoryStream<Path> directory =Files.newDirectoryStream(path);

for (Path childPath: directory) {...

}

if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {...

}

ディレクトリの情報はDirectoryStreamで取得できます。DirectoryStreamはIterableをのサブインタフェース

Pathがディレクトリかどうかを調べるにはFilesユーティリティを使います。

Page 6: Nio2

入出力

Path path = ...;InputStream iStream = Files.newInputStream(path);OutputStream oStream1 = Files.newOutputStream(path);OutputStream oStream2 =

Files.newOutputStream(path, StandardOpenOption.APPEND);

StandardOpenOption.CREATTEStandardOpenOption.CREATE_NEWStandardOpenOption.READStandardOpenOption.WRITEStandardOpenOption.APPEND

Page 7: Nio2

入出力

Path path = ...;BufferedReader reader =

Files.newBufferedReader(path, Charset.defaultCharset());

BufferedWriter writer1 =Files.newBufferedWriter(path, Charset.defaultCharset());

BufferedWriter writer2 =Files.newBufferedWriter(path, Charset.defaultCharset(),

StandardOpenOption.APPEND);

FileChannel や SeekableByteChannel といったファイルチャネルを取得することもできます。

Page 8: Nio2

ファイル・ディレクトリの作成

Path path = fileSystem.getPath(“filename”);Files.createFile(path);

path = fileSystem.getPath(“dirname”);Files.createDirectory(path);

path = fileSystem.getPath(“parentdir/childdir”);Files.createDirectory(path);

Page 9: Nio2

ファイル・ディレクトリのコピー

Path foo = fileSystem.getPath("foo.txt");Path bar = fileSystem.getPath("bar.txt");Path baz = fileSystem.getPath("baz.txt");

// ファイルのコピーFiles.copy(foo, bar);

// ファイルのコピー(上書きコピー)Files.copy(foo, bar, StandardCopyOption.REPLACE_EXISTING);

// ファイルのコピー(属性を含む)Files.copy(foo, baz, StandardCopyOption.COPY_ATTRIBUTES);

StandardCopyOption.REPLACE_EXISTINGStandardCopyOption.COPY_ATTRIBUTESStandardCopyOption.ATOMIC_MOVE

Page 10: Nio2

メタデータ

• Filesクラスのユーティリティメソッド

– ex. Files.setOwner(),Files.getLastModifiedTime()

• Files.getAttribute(),Files.setAttribute()

• FileAttributeViewインタフェース

Page 11: Nio2

Filesクラスのユーティリティメソッドを使ったメタデータの取得設定

FileTime lastModified = File.getFileLastModifiedTime(path);UserPricipal owner = File.getOwner(path);Set<PosixFilePermission> permission =

File.getPosixFilePermission(path);

File.setFileLastModifiedTime(path, lastModified);File.setOwner(path, owner);File.setPosixFilePermission(path, permission);

UserPrincipalLookupService service = FileSystems.getDefault().getUserPrincipalLookupService();

UserPrincipal user = service.lookupPrincipalByName("ap091011");

UserPrincipalはUserPrincipalLookupServiceから取得することが出来る。

Page 12: Nio2

Files.getAttribute()Files.setAttribute()

FileTime lastModified = (FileTime) File.getAttribute(path, “lastModifiedTime”);

FileTime creationTime = (FileTime) File.getAttribute(path, “creationTime”);

UserPrincipal owner = File.getAttribute(path, “acl:onwer”);

File.setAttribute(path, “lastModifiedTime“, lastModified);File.setAttribute(path, “creationTime”, creationTime);File.setAttribute(path, “acl:owner”, owner);

Page 13: Nio2

ファイル・ディレクトリの移動・削除

// ファイルの移動Files.move(foo, bar);// ディレクトリの移動Files.move(dirFoo, dirBar);

// ファイルの削除Files.delete(bar);

// ファイルが存在していなくても、例外をスローしないFiles.deleteIfExists(foo2);

ファイルの移動とディレクトの移動は同じメソッド。同じディレクトリ内のファイル(ディレクトリ)の移動はリネーム

ファイルの移動とディレクトの移動は同じメソッド。ディレクトリの場合ディレクトリ内にファイルがあると例外がスローされる

Page 14: Nio2

FileAttributeViewインタフェース

BasicFileAttributeView attrView = Files.getFileAttributeView(path, BasicFileAttributeView.class);

FileTime lastModified = attrView .readAttributes().lastModifiedTime();FileTime creationTime = attrView .readAttributes().creationTime();

attrView.setTimes(lastModified, lastAccess, creationTime);

AclFileAttributeView acl =Files.getFileAttributeView(path, AclFileAttributeView.class);

UserPrincipal owner = acl.getOwner();

Page 15: Nio2

java.nio.file.FileVisitor

• preVisitDirectory()

–ディレクトリに入る時

• postVisitDirectory()

– ディレクトリから出る時

• visitFile()

– ファイルの訪問時

• visitFileFailed()

– ファイルの訪問に失敗した時

Page 16: Nio2

java.nio.file.WatchServicePath dest = fileSystem.getPath("dest");

WatchService watcher = fileSystem.newWatchService();

dest.register(watcher,

StandardWatchEventKinds.ENTRY_CREATE,

StandardWatchEventKinds.ENTRY_DELETE,

StandardWatchEventKinds.ENTRY_MODIFY);

Pathに対してWatchServiceを登録します。

Page 17: Nio2

java.nio.file.WatchServicewhile (true) {

WatchKey key = null;

try {

key = watcher.take();

} catch (InterruptedException ex) {

break;

}

}

ざんねんながら、自分でポーリングしなくてはなりません。ただし、同期化してくれるので便利といえば、便利です。書き込み途中で何かしようとしちゃう問題とか・・・

Page 18: Nio2

非同期I/O

• AsynchronousSocketChannel

• AsynchronousServerSocketChannel

• AsynchronousFileChannel

• AsynchronousDatagramChannel

SocketChannel, ServerSocketChannel, FileChannel, DatagramChannelの非同期版

それぞれのサブクラスにはなっていません

Page 19: Nio2

非同期I/O

• Future<V>インタフェースを使う方法

• java.nio.channels.CompletionHandlerを使う方法

非同期を実現するのに2つの方法がある。

Page 20: Nio2

AsynchronousSocketChannel

AsynchronousSocketChannel client =

AsynchronousSocketChannel.open();

client.connect(server.getLocalAddress()).get();

Future<AsynchronousSocketChannel> acceptFuture = server.accept();

AsynchronousSocketChannel ch = acceptFuture.get();

クライアントソケットの作成

サーバー側でアクセプトしたソケット

Page 21: Nio2

AsynchronousServerSocketChannel(Future)

Future<AsynchronousSocketChannel> acceptFuture = server.accept();

接続を受け付けるまでブロックされます

AsynchronousSocketChannel worker = future.get();

acept()はブロックされません。

Page 22: Nio2

AsynchronousServerSocketChannel(CompletionHandler)

acept()はブロックされません。

server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {

public void completed(AsynchronousSocketChannel ch, Void att) {

...

}

public void failed(Throwable exc, Void att) {

...

}

)}

Page 23: Nio2

AsynchronousFileChannel

AsynchronousFileChannel fileChannel =

AsynchronousFileChannel.open(Paths.get("myfile"));

Future<Integer> readFuture = fileChannel.read(dst, pos);

ByteBuffer buffer = ByteBuffer.allocate(1024);

int pos = 0;

while (true) {

buffer.clear();

Future<Integer> future = channel.read(buffer, pos);

int len = future.get();

if (len < 0) {

break;

}

pos += len;

}