Java NIO教程
Java NIO之Selector(选择器)
例子
Channel Buffer:
private static void useNIO(){
RandomAccessFile randomAccessFile = null;
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test.txt";
Log.d(TAG, "zwm, filePath:" + filePath);
FileChannel inChannel = null;
try {
randomAccessFile = new RandomAccessFile(new File(filePath), "rw");
inChannel = randomAccessFile.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(5);
int byteReader = inChannel.read(byteBuffer);
while (byteReader != -1) {
Log.d(TAG, "zwm, byteReader: " + byteReader);
byteBuffer.flip();
while (byteBuffer.hasRemaining()) {
Log.d(TAG, "zwm, get byteBuffer: " + (char)byteBuffer.get());
}
byteBuffer.clear();
byteReader = inChannel.read(byteBuffer);
Log.d(TAG, "zwm, byteReader again: " + byteReader);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inChannel.close();
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//test.txt
1234567890
//输出
zwm, filePath:/storage/emulated/0/test.txt
zwm, byteReader: 5
zwm, get byteBuffer: 1
zwm, get byteBuffer: 2
zwm, get byteBuffer: 3
zwm, get byteBuffer: 4
zwm, get byteBuffer: 5
zwm, byteReader again: 5
zwm, byteReader: 5
zwm, get byteBuffer: 6
zwm, get byteBuffer: 7
zwm, get byteBuffer: 8
zwm, get byteBuffer: 9
zwm, get byteBuffer: 0
zwm, byteReader again: -1
private static void useNIO() {
String newData = "New String to write to file..." + System.currentTimeMillis();
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
RandomAccessFile randomAccessFile = null;
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test.txt";
Log.d(TAG, "zwm, filePath:" + filePath + ", file exist: " + new File(filePath).exists());
FileChannel inChannel = null;
try {
randomAccessFile = new RandomAccessFile(new File(filePath), "rw");
inChannel = randomAccessFile.getChannel();
while(buf.hasRemaining()) {
Log.d(TAG, "zwm, while loop");
inChannel.write(buf);
}
Log.d(TAG, "zwm, position: " + inChannel.position());
Log.d(TAG, "zwm, size: " + inChannel.size());
inChannel.truncate(10);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inChannel.close();
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//输出
zwm, filePath:/storage/emulated/0/test.txt, file exist: true
zwm, while loop
zwm, position: 43
zwm, size: 43
//test.txt
New String
Scattering Reads:
private static void useNIO(){
RandomAccessFile randomAccessFile = null;
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test.txt";
Log.d(TAG, "zwm, filePath:" + filePath);
FileChannel inChannel = null;
try {
randomAccessFile = new RandomAccessFile(new File(filePath), "rw");
inChannel = randomAccessFile.getChannel();
ByteBuffer header = ByteBuffer.allocate(3);
ByteBuffer body = ByteBuffer.allocate(7);
ByteBuffer[] bufferArray = { header, body };
inChannel.read(bufferArray);
header.flip();
while (header.hasRemaining()) {
Log.d(TAG, "zwm, get header: " + (char)header.get());
}
body.flip();
while (body.hasRemaining()) {
Log.d(TAG, "zwm, get body: " + (char)body.get());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inChannel.close();
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//test.txt
1234567890
//输出
zwm, filePath:/storage/emulated/0/test.txt
zwm, get header: 1
zwm, get header: 2
zwm, get header: 3
zwm, get body: 4
zwm, get body: 5
zwm, get body: 6
zwm, get body: 7
zwm, get body: 8
zwm, get body: 9
zwm, get body: 0
Gathering Writes:
private static void useNIO(){
RandomAccessFile randomAccessFile = null;
RandomAccessFile randomAccessFile2 = null;
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test.txt";
String filePath2 = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test2.txt";
Log.d(TAG, "zwm, filePath:" + filePath + ", file exist: " + new File(filePath).exists());
Log.d(TAG, "zwm, filePath2:" + filePath2 + ", file exist: " + new File(filePath2).exists());
FileChannel inChannel = null;
FileChannel inChannel2 = null;
try {
randomAccessFile = new RandomAccessFile(new File(filePath), "rw");
randomAccessFile2 = new RandomAccessFile(new File(filePath2), "rw");
inChannel = randomAccessFile.getChannel();
inChannel2 = randomAccessFile2.getChannel();
ByteBuffer header = ByteBuffer.allocate(3);
ByteBuffer body = ByteBuffer.allocate(7);
ByteBuffer[] bufferArray = { header, body };
inChannel.read(bufferArray);
header.flip();
while (header.hasRemaining()) {
Log.d(TAG, "zwm, get header: " + (char)header.get());
}
body.flip();
while (body.hasRemaining()) {
Log.d(TAG, "zwm, get body: " + (char)body.get());
}
header.flip();
body.flip();
ByteBuffer[] bufferArray2 = { body, header };
inChannel2.write(bufferArray2);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inChannel2.close();
inChannel.close();
randomAccessFile2.close();
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//test.txt
1234567890
//输出
zwm, filePath:/storage/emulated/0/test.txt, file exist: true
zwm, filePath2:/storage/emulated/0/test2.txt, file exist: true
zwm, get header: 1
zwm, get header: 2
zwm, get header: 3
zwm, get body: 4
zwm, get body: 5
zwm, get body: 6
zwm, get body: 7
zwm, get body: 8
zwm, get body: 9
zwm, get body: 0
//test2.txt
4567890123
FileChannel#transferFrom():
private static void useNIO(){
RandomAccessFile randomAccessFile = null;
RandomAccessFile randomAccessFile2 = null;
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test.txt";
String filePath2 = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test2.txt";
Log.d(TAG, "zwm, filePath:" + filePath + ", file exist: " + new File(filePath).exists());
Log.d(TAG, "zwm, filePath2:" + filePath2 + ", file exist: " + new File(filePath2).exists());
FileChannel inChannel = null;
FileChannel inChannel2 = null;
try {
randomAccessFile = new RandomAccessFile(new File(filePath), "rw");
randomAccessFile2 = new RandomAccessFile(new File(filePath2), "rw");
inChannel = randomAccessFile.getChannel();
inChannel2 = randomAccessFile2.getChannel();
long position = 0;
long count = inChannel.size();
inChannel2.transferFrom(inChannel, position, count);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inChannel2.close();
inChannel.close();
randomAccessFile2.close();
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//test.txt
1234567890
//test2.txt
1234567890
FileChannel#transferTo():
private static void useNIO(){
RandomAccessFile randomAccessFile = null;
RandomAccessFile randomAccessFile2 = null;
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test.txt";
String filePath2 = Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "test2.txt";
Log.d(TAG, "zwm, filePath:" + filePath + ", file exist: " + new File(filePath).exists());
Log.d(TAG, "zwm, filePath2:" + filePath2 + ", file exist: " + new File(filePath2).exists());
FileChannel inChannel = null;
FileChannel inChannel2 = null;
try {
randomAccessFile = new RandomAccessFile(new File(filePath), "rw");
randomAccessFile2 = new RandomAccessFile(new File(filePath2), "rw");
inChannel = randomAccessFile.getChannel();
inChannel2 = randomAccessFile2.getChannel();
long position = 0;
long count = inChannel.size();
inChannel.transferTo(position, count, inChannel2);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inChannel2.close();
inChannel.close();
randomAccessFile2.close();
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//test.txt
1234567890
//test2.txt
1234567890
ServerSocketChannel SocketChannel 阻塞模式:
private static void useNIO() {
initServerSocketChannel();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, delay end");
initSocketChannel();
}
}, 5000);
}
private static void initServerSocketChannel() {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, initServerSocketChannel, thread: " + Thread.currentThread().getName());
ServerSocketChannel serverSocketChannel = null;
SocketChannel socketChannel = null;
try {
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
while(true){
Log.d(TAG, "zwm, ServerSocketChannel accept start");
socketChannel =
serverSocketChannel.accept();
Log.d(TAG, "zwm, ServerSocketChannel accept end");
String newData = "New String to write to file...";
//生成Buffer,并向Buffer中写数据
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
//切换buffer为读模式
buf.flip();
while(buf.hasRemaining()) {
Log.d(TAG, "zwm, server write start");
socketChannel.write(buf);
Log.d(TAG, "zwm, server write end");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socketChannel.close();
serverSocketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
private static void initSocketChannel() {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, initSocketChannel, thread: " + Thread.currentThread().getName());
SocketChannel socketChannel = null;
try {
socketChannel = SocketChannel.open();
Log.d(TAG, "zwm, client connect start");
socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));
Log.d(TAG, "zwm, client connect end");
ByteBuffer byteBuffer = ByteBuffer.allocate(48);
Log.d(TAG, "zwm, client read start");
int byteReader = socketChannel.read(byteBuffer);
Log.d(TAG, "zwm, client read end");
while (byteReader != -1) {
Log.d(TAG, "zwm, byteReader: " + byteReader);
byteBuffer.flip();
while (byteBuffer.hasRemaining()) {
Log.d(TAG, "zwm, get byteBuffer: " + (char)byteBuffer.get());
}
byteBuffer.clear();
byteReader = socketChannel.read(byteBuffer);
Log.d(TAG, "zwm, byteReader again: " + byteReader);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
//输出
zwm, initServerSocketChannel, thread: Thread-7
zwm, ServerSocketChannel accept start
zwm, delay end
zwm, initSocketChannel, thread: Thread-8
zwm, client connect start
zwm, client connect end
zwm, client read start
zwm, ServerSocketChannel accept end
zwm, server write start
zwm, server write end
zwm, client read end
zwm, ServerSocketChannel accept start
zwm, byteReader: 30
zwm, get byteBuffer: N
zwm, get byteBuffer: e
zwm, get byteBuffer: w
zwm, get byteBuffer:
zwm, get byteBuffer: S
zwm, get byteBuffer: t
zwm, get byteBuffer: r
zwm, get byteBuffer: i
zwm, get byteBuffer: n
zwm, get byteBuffer: g
zwm, get byteBuffer:
zwm, get byteBuffer: t
zwm, get byteBuffer: o
zwm, get byteBuffer:
zwm, get byteBuffer: w
zwm, get byteBuffer: r
zwm, get byteBuffer: i
zwm, get byteBuffer: t
zwm, get byteBuffer: e
zwm, get byteBuffer:
zwm, get byteBuffer: t
zwm, get byteBuffer: o
zwm, get byteBuffer:
zwm, get byteBuffer: f
zwm, get byteBuffer: i
zwm, get byteBuffer: l
zwm, get byteBuffer: e
zwm, get byteBuffer: .
zwm, get byteBuffer: .
zwm, get byteBuffer: .
ServerSocketChannel SocketChannel 非阻塞模式:
private static void useNIO() {
initServerSocketChannel();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, delay end");
initSocketChannel();
}
}, 5000);
}
private static void initServerSocketChannel() {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, initServerSocketChannel, thread: " + Thread.currentThread().getName());
ServerSocketChannel serverSocketChannel = null;
SocketChannel socketChannel = null;
try {
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false); //配置ServerSocketChannel为非阻塞模式
while(true){
//Log.d(TAG, "zwm, ServerSocketChannel accept start");
socketChannel = serverSocketChannel.accept();
//Log.d(TAG, "zwm, ServerSocketChannel accept end, socketChannel: " + socketChannel);
while(socketChannel != null) { //需要判断是否为空
socketChannel.configureBlocking(false); //配置SocketChannel为非阻塞模式
String newData = "New String to write to file...";
//生成Buffer,并向Buffer中写数据
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
//切换buffer为读模式
buf.flip();
while (buf.hasRemaining()) {
Log.d(TAG, "zwm, server write start");
socketChannel.write(buf);
Log.d(TAG, "zwm, server write end");
}
return;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socketChannel.close();
serverSocketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
private static void initSocketChannel() {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, initSocketChannel, thread: " + Thread.currentThread().getName());
SocketChannel socketChannel = null;
try {
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false); //配置SocketChannel为非阻塞模式
Log.d(TAG, "zwm, client connect start");
socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));
Log.d(TAG, "zwm, client connect end");
while(!socketChannel.finishConnect() ) { //需要判断是否完成连接
}
Log.d(TAG, "zwm, SocketChannel finish connect");
ByteBuffer byteBuffer = ByteBuffer.allocate(48);
Log.d(TAG, "zwm, client read start");
int byteReader = socketChannel.read(byteBuffer);
Log.d(TAG, "zwm, client read end");
while (byteReader != -1) {
Log.d(TAG, "zwm, byteReader: " + byteReader);
byteBuffer.flip();
while (byteBuffer.hasRemaining()) {
Log.d(TAG, "zwm, get byteBuffer: " + (char) byteBuffer.get());
}
byteBuffer.clear();
byteReader = socketChannel.read(byteBuffer);
Log.d(TAG, "zwm, byteReader again: " + byteReader);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
//输出
zwm, initServerSocketChannel, thread: Thread-7
zwm, delay end
zwm, initSocketChannel, thread: Thread-8
zwm, client connect start
zwm, client connect end
zwm, SocketChannel finish connect
zwm, client read start
zwm, server write start
zwm, client read end
zwm, byteReader: 0
zwm, server write end
zwm, byteReader again: 30
zwm, byteReader: 30
zwm, get byteBuffer: N
zwm, get byteBuffer: e
zwm, get byteBuffer: w
zwm, get byteBuffer:
zwm, get byteBuffer: S
zwm, get byteBuffer: t
zwm, get byteBuffer: r
zwm, get byteBuffer: i
zwm, get byteBuffer: n
zwm, get byteBuffer: g
zwm, get byteBuffer:
zwm, get byteBuffer: t
zwm, get byteBuffer: o
zwm, get byteBuffer:
zwm, get byteBuffer: w
zwm, get byteBuffer: r
zwm, get byteBuffer: i
zwm, get byteBuffer: t
zwm, get byteBuffer: e
zwm, get byteBuffer:
zwm, get byteBuffer: t
zwm, get byteBuffer: o
zwm, get byteBuffer:
zwm, get byteBuffer: f
zwm, get byteBuffer: i
zwm, get byteBuffer: l
zwm, get byteBuffer: e
zwm, get byteBuffer: .
zwm, get byteBuffer: .
zwm, get byteBuffer: .
zwm, byteReader again: -1
Selector:
private static void useNIO() {
initServerSocketChannel();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, delay end");
initSocketChannel();
}
}, 5000);
}
private static void initServerSocketChannel() {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, initServerSocketChannel, thread: " + Thread.currentThread().getName());
try {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress("127.0.0.1", 9999));
ssc.configureBlocking(false);
Selector selector = Selector.open();
// 注册 channel,并且指定感兴趣的事件是 Accept
ssc.register(selector, SelectionKey.OP_ACCEPT);
ByteBuffer readBuff = ByteBuffer.allocate(1024);
ByteBuffer writeBuff = ByteBuffer.allocate(128);
writeBuff.put("From server".getBytes());
while (true) {
int ready = selector.select();
Log.d(TAG, "zwm, ready: " + ready);
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
if (key.isAcceptable()) {
Log.d(TAG, "zwm, isAcceptable");
// 创建新的连接,并且把连接注册到selector上,而且,
// 声明这个channel只对读操作感兴趣。
SocketChannel socketChannel = ssc.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
}
else if (key.isReadable()) {
Log.d(TAG, "zwm, isReadable");
SocketChannel socketChannel = (SocketChannel) key.channel();
readBuff.clear();
socketChannel.read(readBuff);
readBuff.flip();
while (readBuff.hasRemaining()) {
Log.d(TAG, "zwm, server get readBuff: " + (char) readBuff.get());
}
key.interestOps(SelectionKey.OP_WRITE);
}
else if (key.isWritable()) {
Log.d(TAG, "zwm, isWritable");
writeBuff.flip();
SocketChannel socketChannel = (SocketChannel) key.channel();
socketChannel.write(writeBuff);
key.interestOps(SelectionKey.OP_READ);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private static void initSocketChannel() {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, initSocketChannel, thread: " + Thread.currentThread().getName());
try {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));
ByteBuffer writeBuffer = ByteBuffer.allocate(32);
ByteBuffer readBuffer = ByteBuffer.allocate(32);
writeBuffer.put("From client".getBytes());
writeBuffer.flip();
socketChannel.write(writeBuffer);
readBuffer.clear();
socketChannel.read(readBuffer);
readBuffer.flip();
while (readBuffer.hasRemaining()) {
Log.d(TAG, "zwm, client get readBuffer: " + (char) readBuffer.get());
}
} catch (IOException e) {
}
}
}).start();
}
//输出
zwm, initServerSocketChannel, thread: Thread-7
zwm, delay end
zwm, initSocketChannel, thread: Thread-8
zwm, ready: 1
zwm, isAcceptable
zwm, ready: 1
zwm, isReadable
zwm, server get readBuff: F
zwm, server get readBuff: r
zwm, server get readBuff: o
zwm, server get readBuff: m
zwm, server get readBuff:
zwm, server get readBuff: c
zwm, server get readBuff: l
zwm, server get readBuff: i
zwm, server get readBuff: e
zwm, server get readBuff: n
zwm, server get readBuff: t
zwm, ready: 1
zwm, isWritable
zwm, client get readBuffer: F
zwm, client get readBuffer: r
zwm, client get readBuffer: o
zwm, client get readBuffer: m
zwm, client get readBuffer:
zwm, client get readBuffer: s
zwm, client get readBuffer: e
zwm, client get readBuffer: r
zwm, client get readBuffer: v
zwm, client get readBuffer: e
zwm, client get readBuffer: r
DatagramChannel:
private static void useNIO() {
initServerSocketChannel();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, delay end");
initSocketChannel();
}
}, 5000);
}
private static void initServerSocketChannel() {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, initServerSocketChannel, thread: " + Thread.currentThread().getName());
try {
DatagramChannel channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(9999));
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
channel.receive(buf);
buf.flip();
while (buf.hasRemaining()) {
Log.d(TAG, "zwm, server get buf: " + (char) buf.get());
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private static void initSocketChannel() {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "zwm, initSocketChannel, thread: " + Thread.currentThread().getName());
try {
DatagramChannel channel = DatagramChannel.open();
String newData = "New String to write to file";
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
int bytesSent = channel.send(buf, new InetSocketAddress("127.0.0.1", 9999));
Log.d(TAG, "zwm, client bytesSent: " + bytesSent);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
//输出
zwm, initServerSocketChannel, thread: Thread-7
zwm, delay end
zwm, initSocketChannel, thread: Thread-8
zwm, server get buf: N
zwm, server get buf: e
zwm, server get buf: w
zwm, server get buf:
zwm, server get buf: S
zwm, server get buf: t
zwm, server get buf: r
zwm, server get buf: i
zwm, server get buf: n
zwm, server get buf: g
zwm, server get buf:
zwm, server get buf: t
zwm, server get buf: o
zwm, server get buf:
zwm, server get buf: w
zwm, server get buf: r
zwm, server get buf: i
zwm, server get buf: t
zwm, server get buf: e
zwm, server get buf:
zwm, server get buf: t
zwm, server get buf: o
zwm, server get buf:
zwm, server get buf: f
zwm, server get buf: i
zwm, server get buf: l
zwm, server get buf: e
zwm, client bytesSent: 27
Pipe:
private static void useNIO() {
try {
Pipe pipe = Pipe.open();
Pipe.SinkChannel sinkChannel = pipe.sink();
String newData = "New String to write to file";
ByteBuffer writeBuffer = ByteBuffer.allocate(48);
writeBuffer.clear();
writeBuffer.put(newData.getBytes());
writeBuffer.flip();
while(writeBuffer.hasRemaining()) {
sinkChannel.write(writeBuffer);
}
Pipe.SourceChannel sourceChannel = pipe.source();
ByteBuffer readBuffer = ByteBuffer.allocate(48);
int bytesRead = sourceChannel.read(readBuffer);
Log.d(TAG, "zwm, bytesRead: " + bytesRead);
readBuffer.flip();
while (readBuffer.hasRemaining()) {
Log.d(TAG, "zwm, get readBuffer: " + (char) readBuffer.get());
}
} catch (IOException e) {
e.printStackTrace();
}
}
//输出
zwm, bytesRead: 27
zwm, get readBuffer: N
zwm, get readBuffer: e
zwm, get readBuffer: w
zwm, get readBuffer:
zwm, get readBuffer: S
zwm, get readBuffer: t
zwm, get readBuffer: r
zwm, get readBuffer: i
zwm, get readBuffer: n
zwm, get readBuffer: g
zwm, get readBuffer:
zwm, get readBuffer: t
zwm, get readBuffer: o
zwm, get readBuffer:
zwm, get readBuffer: w
zwm, get readBuffer: r
zwm, get readBuffer: i
zwm, get readBuffer: t
zwm, get readBuffer: e
zwm, get readBuffer:
zwm, get readBuffer: t
zwm, get readBuffer: o
zwm, get readBuffer:
zwm, get readBuffer: f
zwm, get readBuffer: i
zwm, get readBuffer: l
zwm, get readBuffer: e
产生可写的、可读可写的及可读的通道:
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
//可写的通道
try {
FileChannel fc = new FileOutputStream(filePath).getChannel();
fc.write(ByteBuffer.wrap("Some text".getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
Some text
//可读可写的通道
try {
FileChannel fc = new RandomAccessFile(filePath, "rw").getChannel();
fc.position(fc.size()); //Move to the end
fc.write(ByteBuffer.wrap("Some more".getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
Some textSome text
//可读的通道
try {
FileChannel fc = new FileInputStream(filePath).getChannel();
ByteBuffer buff = ByteBuffer.allocate(1024);
fc.read(buff);
buff.flip();
while(buff.hasRemaining()) {
Log.d(TAG, "zwm, char: " + (char)buff.get());
}
} catch (IOException e) {
e.printStackTrace();
}
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, char: S
zwm, char: o
zwm, char: m
zwm, char: e
zwm, char:
zwm, char: t
zwm, char: e
zwm, char: x
zwm, char: t
zwm, char: S
zwm, char: o
zwm, char: m
zwm, char: e
zwm, char:
zwm, char: m
zwm, char: o
zwm, char: r
zwm, char: e
简单文件复制程序(不推荐):
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
FileChannel in = new FileInputStream(filePath).getChannel();
FileChannel out = new FileOutputStream(filePathOutput).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(in.read(buffer) != -1) {
buffer.flip();
out.write(buffer);
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
Some textSome text
//IOTestOutput.txt
Some textSome text
将一个通道和另一个通道直接相连(推荐):
try {
FileChannel in = new FileInputStream(filePath).getChannel();
FileChannel out = new FileOutputStream(filePathOutput).getChannel();
//in.transferTo(0, in.size(), out); //方法1
out.transferFrom(in, 0, in.size()); //方法2
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
Some textSome text
//IOTestOutput.txt
Some textSome text
转换数据:
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
FileChannel fc = new FileInputStream(filePath).getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
fc.read(byteBuffer);
byteBuffer.flip();
//不起作用,输出乱码
Log.d(TAG, "zwm, output: " + byteBuffer.asCharBuffer());
//方法1,输出解码
byteBuffer.rewind();
String encoding = System.getProperty("file.encoding");
Log.d(TAG, "zwm, encoding: " + encoding);
CharBuffer charBuffer = Charset.forName(encoding).decode(byteBuffer);
Log.d(TAG, "zwm, method 1, output: " + charBuffer);
//方法2,输入编码,输出转换
fc = new FileOutputStream(filePath).getChannel();
fc.write(ByteBuffer.wrap("Some text".getBytes("UTF-16BE")));
fc.close();
fc = new FileInputStream(filePath).getChannel();
byteBuffer.clear();
fc.read(byteBuffer);
byteBuffer.flip();
Log.d(TAG, "zwm, method 2, output: " + byteBuffer.asCharBuffer());
//方法3,输入转换,输出转换
fc = new FileOutputStream(filePath).getChannel();
byteBuffer = ByteBuffer.allocate(24); //More than needed
byteBuffer.asCharBuffer().put("Some text");
fc.write(byteBuffer);
fc.close();
fc = new FileInputStream(filePath).getChannel();
byteBuffer.clear();
fc.read(byteBuffer);
byteBuffer.flip();
Log.d(TAG, "zwm, method 3, output: " + byteBuffer.asCharBuffer());
} catch (IOException e) {
e.printStackTrace();
}
//IOTest.txt
Some text
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, output: 卯浥?數
zwm, encoding: UTF-8
zwm, method 1, output: Some text
zwm, method 2, output: Some text
zwm, method 3, output: Some text??????
获取基本类型:
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int i = 0;
while(i++ < byteBuffer.limit()) {
if(byteBuffer.get() != 0) {
Log.d(TAG, "zwm, nonzero");
}
}
Log.d(TAG, "zwm, i: " + i);
byteBuffer.rewind();
byteBuffer.asCharBuffer().put("Howdy!");
char c;
while ((c = byteBuffer.getChar()) != 0) {
Log.d(TAG, "zwm, char: " + c);
}
byteBuffer.rewind();
byteBuffer.asShortBuffer().put((short)471142);
Log.d(TAG, "zwm, short: " + byteBuffer.getShort());
byteBuffer.rewind();
byteBuffer.asIntBuffer().put(99471142);
Log.d(TAG, "zwm, int: " + byteBuffer.getInt());
byteBuffer.rewind();
byteBuffer.asLongBuffer().put(99471142);
Log.d(TAG, "zwm, long: " + byteBuffer.getLong());
byteBuffer.rewind();
byteBuffer.asFloatBuffer().put(99471142);
Log.d(TAG, "zwm, float: " + byteBuffer.getFloat());
byteBuffer.rewind();
byteBuffer.asDoubleBuffer().put(99471142);
Log.d(TAG, "zwm, double: " + byteBuffer.getDouble());
byteBuffer.rewind();
//输出
zwm, i: 1025
zwm, char: H
zwm, char: o
zwm, char: w
zwm, char: d
zwm, char: y
zwm, char: !
zwm, short: 12390
zwm, int: 99471142
zwm, long: 99471142
zwm, float: 9.9471144E7
zwm, double: 9.9471142E7
内存映射文件:
内存映射文件允许我们创建和修改那些因为太大而不能放入内存的文件。
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
int length = (int)new File(filePath).length();
Log.d(TAG, "zwm, file length: " + length);
try {
MappedByteBuffer out = new RandomAccessFile(filePath, "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length);
for(int i=0; i<length; i++) {
out.put((byte)'x'); //写操作
}
Log.d(TAG, "zwm, Finished writing");
for(int i=0; i<length; i++) {
Log.d(TAG, "zwm, char: " + (char)out.get(i)); //读操作
}
} catch (IOException e) {
e.printStackTrace();
}
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, file length: 24
zwm, Finished writing
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
zwm, char: x
文件加锁:
JDK1.4引入了文件加锁机制,它允许我们同步访问某个作为共享资源的文件。
文件锁对其他的操作系统进程是可见的,因为Java的文件加锁直接映射到了本地操作系统的加锁工具。
相关方法:
tryLock() //非阻塞式,它设法获取锁,如果不能获得(当其他一些进程已经持有相同的锁,并且不共享时),它将直接从方法调用返回
tryLock(long position, long size, boolean shared) //对文件的一部分上锁,加锁区域为从position到position+size,shared指定释放是否是共享锁
lock() //阻塞式,它要阻塞进程直至锁可以获得,或调用lock()的线程中断,或调用lock()的通道关闭
lock(long position, long size, boolean shared) //对文件的一部分上锁,加锁区域为从position到position+size,shared指定释放是否是共享锁
release() //释放锁
isShared() //是否为共享锁
无参数的加锁方法会对整个文件进行加锁,文件变大后也是如此。
有参数的加锁方法会对文件的固定区域加锁,文件变大后也是如此。
对独占锁或者共享锁的支持必须由底层的操作系统提供,如果操作系统不支持共享锁并为每一个请求都创建一个锁,那么它就会使用独占锁。
文件加锁简单例子:
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
FileOutputStream fos = new FileOutputStream(filePath);
FileLock fl = fos.getChannel().tryLock();
if(fl != null) {
Log.d(TAG, "zwm, Locked File");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
fl.release();
Log.d(TAG, "zwm, Released Lock");
}
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, Locked File
zwm, Released Lock
对映射文件的部分加锁:
public class LockAndModify extends Thread {
private FileChannel fc;
private ByteBuffer buff;
private int start, end;
public LockAndModify(FileChannel fc, ByteBuffer mob, int start, int end) {
this.fc = fc;
this.start = start;
this.end = end;
mob.limit(end);
mob.position(start);
buff = mob.slice();
start();
}
public void run() {
try {
Log.d(TAG, "zwm, Locked: " + start + " to " + end);
FileLock fl = fc.lock(start, end, false);
Log.d(TAG, "zwm, buff position: " + buff.position() + ", buff limit: " + buff.limit());
while(buff.position() < buff.limit()) {
Log.d(TAG, "zwm, buff position: " + buff.position());
buff.put((byte) 'k');
}
fl.release();
Log.d(TAG, "zwm, Release: " + start + " to " + end);
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "zwm, IOException");
}
}
}
//测试代码
String fileDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "IOTest.txt";
final String filePath = fileDir + File.separator + fileName;
String fileNameOutput = "IOTestOutput.txt";
String filePathOutput = fileDir + File.separator + fileNameOutput;
boolean fileExist = new File(filePath).exists();
Log.d(TAG, "zwm, filePath: " + filePath + ", fileExist: " + fileExist);
try {
final int length = (int)new File(filePath).length();
Log.d(TAG, "zwm, length: " + length);
FileChannel fc = new RandomAccessFile(filePath, "rw").getChannel();
final MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);
for(int i=0; i<length; i++) {
out.put((byte)'e'); //写操作
}
new LockAndModify(fc, out, 0, 0+length/3); //部分加锁
new LockAndModify(fc, out, length/2, length/2+length/4); //部分加锁
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "zwm, IOException");
}
//输出
zwm, filePath: /storage/emulated/0/IOTest.txt, fileExist: true
zwm, length: 9
zwm, Locked: 4 to 6
zwm, Locked: 0 to 3
zwm, buff position: 0, buff limit: 3
zwm, buff position: 0
zwm, buff position: 1
zwm, buff position: 2
zwm, Release: 0 to 3
zwm, buff position: 0, buff limit: 2
zwm, buff position: 0
zwm, buff position: 1
zwm, Release: 4 to 6
//IOTest.txt
kkkekkeee