NIO/NIO2

★Event

import java.nio.file.Path;

import java.nio.file.Paths;

import java.nio.file.StandardWatchEventKinds;

import java.nio.file.WatchEvent;

import java.nio.file.WatchKey;

import java.nio.file.WatchService;

Path path = Paths.get("/home/work");

System.out.println("Watching ...");

try {

WatchService watcher = path.getFileSystem().newWatchService();

path.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);

WatchKey watckKey = watcher.take();

List<WatchEvent<?>> events = watckKey.pollEvents();

for (WatchEvent<?> event : events) {

System.out.println("File created:" + event.context().toString());

}

} catch (Exception e) {

...

}

★Charset

import java.nio.ByteBuffer;

import java.nio.CharBuffer;

import java.nio.charset.Charset;

import java.nio.charset.CharsetEncoder;

String str = "...";

Charset charset = Charset.forName("ISO-8859-1");

CharsetEncoder encoder = charset.newEncoder();

ByteBuffer buf = encoder.encode(CharBuffer.wrap(str));

byte[] byteArray = new byte[100];

int bytesRead = fileInputStream.read(byteArray);

ByteBuffer byteBuffer = ByteBuffer.allocate(100);

int bytesRead = fileChannel.read(byteBuffer);

ByteBuffer header = ByteBuffer.allocate (50);

ByteBuffer footer = ByteBuffer.allocate (50);

ByteBuffer[] buffers = { header, footer };

fileChannel.read(buffers);

★Memory mapping

import java.io.RandomAccessFile;

import java.nio.MappedByteBuffer;

import java.nio.channels.FileChannel;

static int MEM_MAP_SIZE = 20 * 1024 * 1024;

static String FILE_PATH = "...";

try (RandomAccessFile memoryMappedFile

= new RandomAccessFile(FILE_PATH, "rw")) {

MappedByteBuffer out = memoryMappedFile.getChannel().map(

FileChannel.MapMode.READ_WRITE, 0, MEM_MAP_SIZE);

// Write

for (int i = 0; i < MEM_MAP_SIZE; i++) {

out.put((byte) 'A');

}

// Read

for (int i = 0; i < 50; i++) {

System.out.print((char) out.get(i));

}

}

★SelectorとChannel

import java.net.InetSocketAddress;

import java.net.ServerSocket;

import java.nio.ByteBuffer;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

public class MultiPortEcho {

private int ports[];

private ByteBuffer echoBuffer = ByteBuffer.allocate(1024);

public MultiPortEcho(int ports[]) throws IOException {

this.ports = ports;

init();

}

private void init() throws IOException {

Selector selector = Selector.open();

for (int i = 0; i < ports.length; i++) {

ServerSocketChannel ssc = ServerSocketChannel.open();

ssc.configureBlocking(false);

ServerSocket ss = ssc.socket();

InetSocketAddress address = new InetSocketAddress(ports[i]);

ss.bind(address);

ssc.register(selector, SelectionKey.OP_ACCEPT);

System.out.println("Listening on " + ports[i]);

}

while (true) {

selector.select();

Set<SelectionKey> selectedKeys = selector.selectedKeys();

Iterator<SelectionKey> it = selectedKeys.iterator();

while (it.hasNext()) {

SelectionKey key = (SelectionKey) it.next();

if ((key.readyOps() & SelectionKey.OP_ACCEPT)

== SelectionKey.OP_ACCEPT) {

ServerSocketChannel ssc

= (ServerSocketChannel) key.channel();

SocketChannel sc = ssc.accept();

sc.configureBlocking(false);

sc.register(selector, SelectionKey.OP_READ);

it.remove();

System.out.println("Connection from " + sc);

} else if ((key.readyOps() & SelectionKey.OP_READ)

== SelectionKey.OP_READ) {

SocketChannel sc = (SocketChannel) key.channel();

int readBytes = 0;

while (true) {

echoBuffer.clear();

int numberOfBytes = sc.read(echoBuffer);

if (numberOfBytes <= 0) {

break;

}

echoBuffer.flip();

sc.write(echoBuffer);

readBytes += numberOfBytes;

}

System.out.println("Read " + readBytes + " from " + sc);

it.remove();

}

}

}

}

public static void main(String args[]) throws Exception {

if (args.length <= 0) {

System.err.println("Usage: java MultiPortEcho port [port ...]");

System.exit(1);

}

int ports[] = new int[args.length];

for (int i = 0; i < args.length; i++) {

ports[i] = Integer.parseInt(args[i]);

}

new MultiPortEcho(ports);

}

}

★Direct Buffer vs Heap Buffer

・Direct Buffer

処理流れ:

ネットワーク・ファイルシステム ⇒ 自作Direct Buffer ⇒ ネットワーク・ファイルシステム

メリット:

データコピー処理を減らすため、性能アップ

デメリット:

new・destroyのコストが高い

利用場面:

ビッグファイルを読み込む・ダウンロードする

重複データの再利用

・Heap Buffer

処理流れ:

ネットワーク・ファイルシステム ⇒ 一時Direct Buffer ⇒ 自作Heap Buffer ⇒ 一時Direct Buffer ⇒ ネットワーク・ファイルシステム

★bufferの状態

0 <= position <= limit <= capacity

flipメソッド(write処理前に呼ぶべき)

limit = position;

position = 0;

clearメソッド(read処理前に呼ぶべき)

limit = capacity

position = 0;