AsynchronousFileChannel
在 Java 7 中,Java NIO 中添加了 AsynchronousFileChannel,也就是是异步地将数 据写入文件。
创建 AsynchronousFileChannel
通过静态方法 open()创建
Path path = Paths.get("d:\\1.txt");
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
open()方法的第一个参数指向与 AsynchronousFileChannel
相关联文件的 Path 实例。
第二个参数是一个或多个打开选项,它告诉 AsynchronousFileChannel
在文件上执行什么操作。在本例中,我们使用了 StandardOpenOption.READ
选项,表示该文件将被打开阅读。
通过 Future 读取数据
可以通过两种方式从 AsynchronousFileChannel
读取数据。第一种方式是调用返回 Future
的 read()方法
Path path = Paths.get("d:\\1.txt");
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
Future<Integer> operation = fileChannel.read(buffer, position);
while(!operation.isDone());
//返回读取到的字节数目
System.out.println(operation.get());
buffer.flip();
byte[] data = new byte[buffer.limit()];
buffer.get(data);
System.out.println(new String(data));
buffer.clear();
上述代码:
(1)创建了一个 AsynchronousFileChannel
(2)创建一个 ByteBuffer,它被传递给 read()方法作为参数,以及一个 0 的位置。
(3)在调用 read()之后,循环,直到返回的 isDone()方法返回 true。
(4)读取操作完成后,数据读取到 ByteBuffer 中,然后打印到 System.out 中。
通过 CompletionHandler 读取数据
第二种方法是调用 read()方法,该方法将一个 CompletionHandler
作为参数
示例:
Path path = Paths.get("d:\\1.txt");
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);;
ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
fileChannel.read(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
//result 读取到的字节数目
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println("result = " + result);
attachment.flip();
byte[] data = new byte[attachment.limit()];
attachment.get(data);
System.out.println(new String(data));
attachment.clear();
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
}
});
(1)读取操作完成,将调用 CompletionHandler
的 completed()
方法。
(2)对于completed()方法的参数传递一个整数,它告诉我们读取了多少字节,以及传递给 read()方法的“附件”。“附件”是 read()方法的第三个参数。在本代码中,它是 ByteBuffer,数据也被读取。
(3)如果读取操作失败,则将调用 CompletionHandler
的 failed()
方法。
通过 Future和CompletionHandler 写入数据
大部分代码与上面代码类似,这里不过多介绍。
Future
写入数据:open时指定StandardOpenOption.WRITE
写操作
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
Future<Integer> operation = fileChannel.write(buffer, position);
buffer.clear();
while(!operation.isDone());
System.out.println("Write over");
CompletionHandler
方式写入数据:
fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println("bytes written: " + result);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("Write failed");
exc.printStackTrace();
}
});
当写操作完成时,将会调用 CompletionHandler
的 completed()
方法。如果写失 败,则会调用 failed()
方法。
字符集(Charset)
java 中使用 Charset 来表示字符集编码对象
Charset 常用静态方法
public static Charset forName(String charsetName)//通过编码类型获得 Charset 对象
public static SortedMap<String,Charset> availableCharsets()//获得系统支持的所有编码方式
public static Charset defaultCharset()//获得虚拟机默认的编码方式
public static boolean isSupported(String charsetName)//判断是否支持该编码类型
Charset 常用普通方法
public final String name()//获得 Charset 对象的编码类型(String)
public abstract CharsetEncoder newEncoder()//获得编码器对象
public abstract CharsetDecoder newDecoder()//获得解码器对象
示例:
Charset charset = Charset.forName("UTF-8");
//1.获取编码器
CharsetEncoder charsetEncoder = charset.newEncoder();
//2.获取解码器
CharsetDecoder charsetDecoder = charset.newDecoder();
//3.获取需要解码编码的数据
CharBuffer charBuffer = CharBuffer.allocate(1024);
charBuffer.put("字符集编码解码");
charBuffer.flip();
//4.编码
ByteBuffer byteBuffer = charsetEncoder.encode(charBuffer);
System.out.println("编码后:");
for (int i=0; i<byteBuffer.limit(); i++) {
System.out.println(byteBuffer.get());
}
//5.解码
byteBuffer.flip();
CharBuffer charBuffer1 = charsetDecoder.decode(byteBuffer);
System.out.println("解码后:");
System.out.println(charBuffer1.toString());
System.out.println("指定其他格式解码:");
Charset charset1 = Charset.forName("GBK");
byteBuffer.flip();
CharBuffer charBuffer2 = charset1.decode(byteBuffer);
System.out.println(charBuffer2.toString());
//6.获取 Charset 所支持的字符编码
Map<String ,Charset> map = Charset.availableCharsets();
Set<Map.Entry<String,Charset>> set = map.entrySet();
for (Map.Entry<String,Charset> entry: set) {
System.out.println(entry.getKey() + "=" + entry.getValue().toString());
}
运行结果: