Java I/O

Input : 输入 -> 从外部往内存 Output : 输出 -> 从内存往外部 Java 中是通过流Stream的方式,实现文件的读写,本质上就是通过stream流进行读和写

buffer read
image.png

buffer write
image.png

  1. private static void io6() {
  2. try (Socket socket = new Socket("hencoder.com", 80);
  3. //发送请求报文
  4. BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  5. //接收响应报文的
  6. BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
  7. // Socket socket = new Socket("hencoder.com", 80);
  8. //发送请求报文
  9. // BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  10. //接收响应报文的
  11. // BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  12. writer.write("GET / HTTP/1.1\n" +
  13. "Host: www.example.com\n\n");
  14. writer.flush();
  15. String message;
  16. while ((message = reader.readLine()) != null) {
  17. System.out.println(message);//HTTP/1.1 200 OK
  18. }
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. private static void io7() {
  24. try (ServerSocket serverSocket = new ServerSocket(80);
  25. //阻塞 等客户端连接服务端
  26. Socket socket = serverSocket.accept();
  27. BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  28. BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
  29. //创建一个服务端Socket
  30. // ServerSocket serverSocket = new ServerSocket(80);
  31. //阻塞 等客户端连接服务端
  32. // Socket socket = serverSocket.accept();
  33. writer.write("hello test");
  34. writer.flush();
  35. } catch (IOException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. /**
  40. * 读写字符串
  41. */
  42. private static void io3() {
  43. //try() 自动关闭流
  44. try (InputStream inputStream = new FileInputStream("./io.text.txt");
  45. Reader reader = new InputStreamReader(inputStream);
  46. BufferedReader bufferedReader = new BufferedReader(reader)
  47. ) {
  48. //Reader reader = new FileReader();//直接戳文件
  49. // Reader reader = new InputStreamReader(inputStream);//reader -> stream -> file
  50. //Reader Writer 写字符串的流
  51. //BufferedReader 可以读取一行数据
  52. // BufferedReader bufferedReader = new BufferedReader(reader);//bufferreader -> reader -> stream -> file
  53. System.out.println(bufferedReader.readLine());
  54. } catch (FileNotFoundException e) {
  55. e.printStackTrace();
  56. } catch (IOException e) {
  57. e.printStackTrace();
  58. }
  59. }
  60. /**
  61. * 读文件 input,从外部输入到内存
  62. * 读文件和写文件,都需要插一个管子,
  63. */
  64. private static void io2() {
  65. InputStream inputStream = null;
  66. try {
  67. inputStream = new FileInputStream("./io.text.txt");
  68. System.out.println((char) inputStream.read());
  69. System.out.println((char) inputStream.read());
  70. } catch (FileNotFoundException e) {
  71. e.printStackTrace();
  72. } catch (IOException e) {
  73. e.printStackTrace();
  74. } finally {
  75. try {
  76. if (inputStream != null) {
  77. inputStream.close();
  78. }
  79. } catch (IOException e) {
  80. e.printStackTrace();
  81. }
  82. }
  83. }
  84. /**
  85. * 写文件 output,从内存输出到外部
  86. */
  87. private static void io1() {
  88. //Java 7 的写法,写到try() 当try执行完毕,会自动关闭流
  89. try (OutputStream outputStream = new FileOutputStream("./io.text.txt")) {
  90. //相当于从 程序的内存 和 外部,搭建了一个桥梁
  91. outputStream.write('a');
  92. outputStream.write('b');
  93. //Reader Writer 写字符串的流
  94. } catch (FileNotFoundException e) {
  95. e.printStackTrace();
  96. } catch (IOException e) {
  97. e.printStackTrace();
  98. }
  99. }
  100. /**
  101. * BufferedOutputStream
  102. */
  103. private static void io4() {
  104. //Java 7 的写法,写到try() 当try执行完毕,会自动关闭流
  105. try (OutputStream outputStream = new FileOutputStream("./io.text.txt");
  106. BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) {
  107. // BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
  108. //相当于从 程序的内存 和 外部,搭建了一个桥梁
  109. //c d -> buffer 只是先放到缓冲区了 没有写入到文件中 减少和文件的直接操作 提升性能
  110. bufferedOutputStream.write('q');
  111. bufferedOutputStream.write('a');
  112. //flush 将缓冲区的数据一块 这样效率更高 buffer -> stream -> file
  113. // bufferedOutputStream.flush();
  114. //flush实际意义:手动调用flush 可以先同步一部分数据,后面继续在缓冲区接收数据 当达到某个阈值 调用flush同步数据
  115. //close 关闭的时候 也会将缓冲区的数据 冲到文件中
  116. // bufferedOutputStream.close();
  117. //Reader Writer 写字符串的流
  118. } catch (FileNotFoundException e) {
  119. e.printStackTrace();
  120. } catch (IOException e) {
  121. e.printStackTrace();
  122. }
  123. }
  124. /**
  125. * 循环的读和写
  126. *
  127. * @throws IOException
  128. */
  129. private static void io5() {
  130. try (InputStream inputStream = new BufferedInputStream(new FileInputStream("./io.text.txt"));
  131. OutputStream outputStream = new BufferedOutputStream(new FileOutputStream("./io.new_text.txt"))) {
  132. byte[] data = new byte[1024];
  133. int read;//把外部的文件 读取到data中,read 读取的个数
  134. while ((read = inputStream.read(data)) != -1) {
  135. outputStream.write(data, 0, read);
  136. }
  137. } catch (FileNotFoundException e) {
  138. e.printStackTrace();
  139. } catch (IOException e) {
  140. e.printStackTrace();
  141. }
  142. }

NIO

传统IO:Stream;NIO:Channel 双向,NIO Buffer 可以被操作的;强制使用Buffer(buffer不还用) 支持非阻塞式,默认是阻塞式的,只有网络交互支持非阻塞,文件交互不支持。

image.png

  1. //NIO 非阻塞式 必须是网络交互
  2. private static void io9() {
  3. try {
  4. ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
  5. serverSocketChannel.bind(new InetSocketAddress(80));
  6. serverSocketChannel.configureBlocking(false);//非阻塞
  7. Selector selector = Selector.open();
  8. //accept 行为变成了非阻塞式的
  9. serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
  10. //阻塞的
  11. while (true) {
  12. selector.select();//这里变成了阻塞
  13. for (SelectionKey selectedKey : selector.selectedKeys()) {
  14. if (selectedKey.isAcceptable()) {
  15. SocketChannel socketChannel = serverSocketChannel.accept();
  16. ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
  17. while (socketChannel.read(byteBuffer) != -1) {
  18. byteBuffer.flip();
  19. //还4回去
  20. socketChannel.write(byteBuffer);
  21. byteBuffer.clear();
  22. }
  23. }
  24. }
  25. }
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. private static void io8() {
  31. try {
  32. RandomAccessFile file = new RandomAccessFile("./io.text.txt", "r");
  33. FileChannel channel = file.getChannel();
  34. //将问价内容读取到 buffer中去
  35. ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
  36. channel.read(byteBuffer);
  37. byteBuffer.limit(byteBuffer.position());//把position 交给limit
  38. byteBuffer.position(0);
  39. // byteBuffer.flip(); 等价于上面的两行
  40. System.out.println(Charset.defaultCharset().decode(byteBuffer));
  41. //每次读写完后将position 和 limit重置
  42. byteBuffer.clear();
  43. } catch (FileNotFoundException e) {
  44. e.printStackTrace();
  45. } catch (IOException e) {
  46. e.printStackTrace();
  47. }
  48. }

okio

  1. /**
  2. * 基于插管的 单向:Source 输入、Sink输出
  3. * 支持Buffer 可以对Buffer进行操作 很好用的 不强制使用Buffer
  4. * 和传统IO很像
  5. */
  6. private static void okio() {
  7. try(BufferedSource source = Okio.buffer(Okio.source(new File("./io.text.txt")))) {
  8. //BufferedSource Okio.buffer
  9. System.out.println(source.readUtf8Line());
  10. // Okio.sink().write();
  11. //Okio.source
  12. Buffer buffer = new Buffer();
  13. //读source 写到buffer中去
  14. source.read(buffer,1024);
  15. //读buffer
  16. System.out.println(buffer.readUtf8Line());
  17. } catch (FileNotFoundException e) {
  18. e.printStackTrace();
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. }
  22. }