AsychronousFileChannel
在 Java 7 中, Java NIO 中添加了 AsychronousFileChannel , 也就是异步地写将数据写入文件
1、创建 AynchronousFileChannel
通过静态方法 open 创建
Path path = Paths.get("/xxx/01.txt"); try { AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); } catch (IOException e) { e.printStackTrace(); }
open() 方法的第一个参数指向与 AsynchronousFileChannel 相关联文件的 Path 实例。
第二个参数是一个或者多个打开选项,它告诉 AsynchronousFileChannel 在我呢叫爱你上执行什么操作。在本例子中,我们使用了 StandardOpenOption.READ 选项,表示该文件将被打开阅读。
2、通过 Future 读取数据
可以通过两种方式从 AsynchronousFileChannel 读取数据。第一种方式是调用返回 Futrue 的 read() 方法。
示例:
Path path = Paths.get("/xxx/01.txt"); AsynchronousFileChannel fileChannel = null; try { fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); } catch (IOException e) { e.printStackTrace(); } ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; Future<Integer> future = fileChannel.read(buffer, position); while (!future.isDone()) { ; } buffer.flip(); // while (buffer.remaining() > 0) { // System.out.println(buffer.get()); // } byte[] data = new byte[buffer.limit()]; buffer.get(data); System.out.println(new String(data)); buffer.clear(); fileChannel.close();
上述代码:
(1)创建了一个 AsynchronousFileChannel
(2)创建一个 ByteBuffer , 它被传递给了 read() 方法作为参数,以及第一个 0 的位置。
(3)在调用 read() 之后,循环,知道返回的 isDeme() 方法返回 true。
(4)读取操作完成之后,数据读取到 ByteBuffer 中,然后打印到 System.out 中。
3、通过 CompletionHandler 读取数据
第二种方法是调用 read() 方法,该方法将一个 CompletionHandler 作为参数。
示例:
Path path = Paths.get("/xxx/01.txt"); AsynchronousFileChannel fileChannel = null; try { fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); } catch (IOException e) { e.printStackTrace(); } ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; fileChannel.read(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer result, ByteBuffer attachment) { System.out.println("result : " + result); buffer.flip(); byte[] data = new byte[buffer.limit()]; buffer.get(data); System.out.println(new String(data)); buffer.clear(); } @Override public void failed(Throwable exc, ByteBuffer attachment) { } }); TimeUnit.SECONDS.sleep(1000);
4、通过 Futrue 写数据
示例:
Path path = Paths.get("/xxx/01.txt"); AsynchronousFileChannel fileChannel = null; try { fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE); } catch (IOException e) { e.printStackTrace(); } ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; buffer.put("hello! 2022".getBytes(StandardCharsets.UTF_8)); buffer.flip(); Future<Integer> write = fileChannel.write(buffer, 0); while (!write.isDone()) ; System.out.println("写数据完成"); TimeUnit.SECONDS.sleep(1000);
首先,AsynchronousFileChannel 以写模式打开。然后创建一个 ByteBuffer 并将一些数据写入其中。然后 ByteBuffer 中的数据写入到文件中。最后,检查返回的 Future , 以查看写操作完成时的情况。
注意,文件必须已经存在。如果文件不存在,那么 write() 方法将抛出一个
java.nio.file.NoSuchFileException
。
5、通过 CompletionHandler 写数据
示例:
Path path = Paths.get("/xxx/01.txt"); AsynchronousFileChannel fileChannel = null; try { fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE); } catch (IOException e) { e.printStackTrace(); } ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; buffer.put("hello ! 2022".getBytes(StandardCharsets.UTF_8)); buffer.flip(); fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer result, ByteBuffer attachment) { System.out.println("write completed!!!"); } @Override public void failed(Throwable exc, ByteBuffer attachment) { System.out.println("write failed!!!"); } }); TimeUnit.SECONDS.sleep(1000);
当写操作完成时,将会调用 CompletionHandler 的 completed() 方法。如果写失败则会调用 failed() 方法
字符集(Charset)
java 中的 Charset 来表示字符集编码对象。
Charset 常用静态方法
// 通过编码类型获取 Charset 对象 public static Charset forName(String charsetName) // 获得系统支持的素有编码方式 public static SortedMap<String, Charset> availableCharsets() // 获得虚拟机默认的编码方式 public static defaultCharset() // 判断是否支持该编码类型 public static boolean isSupported(String charsetName)
Charset 常用普通方法
// 获得 Charset 对象编码类型(String) public final String name() // 获得编码器对象 public abstract CharsetEncoder newEncoder() // 获得解码器对象 public abstract CharsetDecoder newDecoder()
代码演示
public class CharsetDemo { public static void main(String[] args) throws CharacterCodingException { // 1、获取 charset 对象 Charset charset = Charset.forName("UTF-8"); // 2、获得编码器对象 CharsetEncoder charsetEncoder = charset.newEncoder(); // 3、创建缓冲区 CharBuffer charBuffer = CharBuffer.allocate(1025); charBuffer.put("hello 2020 ! 加油!"); // 4、编码 charBuffer.flip(); ByteBuffer buffer = charsetEncoder.encode(charBuffer); System.out.println("编码后的字符:"); for (int i = 0; i < buffer.limit(); i++) { System.out.println(buffer.get()); } // 5、获取解码器对象 buffer.flip(); CharsetDecoder charsetDecoder = charset.newDecoder(); // 6、解码 CharBuffer charBuffer1 = charsetDecoder.decode(buffer); System.out.println("解码后的字符:"); System.out.println(charBuffer1.toString()); // 7、通过其他类型的解码器解码 Charset charset1 = Charset.forName("GBK"); CharsetDecoder charsetDecoder1 = charset1.newDecoder(); CharBuffer charBuffer2 = charsetDecoder1.decode(buffer); System.out.println("解码后的字符(GBK):"); System.out.println(charBuffer2.toString()); // 8、获取所有的字符串集 Map<String, Charset> map = Charset.availableCharsets(); map.forEach((k, v) -> System.out.println(k + "=" + v.toString())); } }