在 Java 7 中,Java NIO 中添加了 AsynchronousFileChannel,也就是是异步地将数 据写入文件。
通过静态方法 open()创建
Path path = Paths.get("d:\\1.txt"); AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
open()方法的第一个参数指向与 AsynchronousFileChannel
相关联文件的 Path 实例。
第二个参数是一个或多个打开选项,它告诉 AsynchronousFileChannel
在文件上执行什么操作。在本例中,我们使用了 StandardOpenOption.READ
选项,表示该文件将被打开阅读。
可以通过两种方式从 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 中。
第二种方法是调用 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
写入数据: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()
方法。
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()); }
运行结果: