内容简介:从文件读数据到内存里面,方便操作网络数据和本地文件,操作更加灵活了,所有的操作都是利用String来代替就是 24_io.txt 如果没有 就会帮忙创建,如果有就不会创建,这个就是用java io做的一个基本操作不是直接操作文件,而是直接操作流,通过一根管子,插到这个文件上,然后对这个流进行操作,这样可以对不同的外部对象使用统一的操作形式,不管是往一个文件还是网络还是其他形式,我都是创造一个String的格式,然后往这个String 去写 或者 去存 然后去读 这个String,相当于在程序内部和外界之间搭
- Github: github.com/MicroKibaco…
- 掘金: juejin.im/user/57cf5d…
- csdn:blog.csdn.net/Kibaco
- 微信公众号: 杨正友
学习目标
- java传统io如何使用
- 非阻塞 nio 是怎么回事
- okio 的优势与使用
java传统io: 流
从文件读数据到内存里面,方便操作网络数据和本地文件,操作更加灵活了,所有的操作都是利用String来代替
熟悉java io 的基本操作
就是 24_io.txt 如果没有 就会帮忙创建,如果有就不会创建,这个就是用java io做的一个基本操作
try { // 输出流的管子 final FileOutputStream fileOutputStream = new FileOutputStream("./24_io/24_io.txt"); fileOutputStream.write('a'); fileOutputStream.write('b'); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } 复制代码
不是直接操作文件,而是直接操作流,通过一根管子,插到这个文件上,然后对这个流进行操作,这样可以对不同的外部对象使用统一的操作形式,不管是往一个文件还是网络还是其他形式,我都是创造一个String的格式,然后往这个String 去写 或者 去存 然后去读 这个String,相当于在程序内部和外界之间搭建了一个桥梁 ,我虽然把处理单件事件变复杂了,比如:我一辈子都处理文件,或者一辈子处理网络 ,把这个变复杂了,但是整体上有一个一致性,所以扩展性变更好了,由于这个扩展性,他做的事情也变多了,不止是可以读写文件,还可以和网络交互,而且还有其他形式可以和网络操作,也可以通过其他扩展的String来操作
java 文件的 读取操作
资源的持有会消耗内存,所以我们在不需要这些资源的时候我们需要释放这些资源,所谓的释放就是把文件关闭,把文件的关闭本质就是把流给舍弃调,java 7 以下我们需要在 finally处理如下:
InputStream sFileInputStream = null; try { sFileInputStream = new FileInputStream("./24_io/24_io.txt"); System.out.println((char) sFileInputStream.read()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (sFileInputStream != null) { try { sFileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } 复制代码
java 7 以及以上 在 try () 处理即可,自动关流
try (InputStream sFileInputStream = new FileInputStream("./24_io/24_io.txt")) { System.out.println((char) sFileInputStream.read()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } 复制代码
所有的流都实现了 Closeable,所有的 Closeable 如果在try 里面做初始化 都会被自动关闭
public abstract class InputStream implements Closeable {} 复制代码
怎么和文件进行互操作,怎么把文件转换成字符?
try (InputStream sFileInputStream = new FileInputStream("./24_io/24_io.txt")) { Reader inputStreamReader = new InputStreamReader(sFileInputStream); final BufferedReader bufferedInputStream = new BufferedReader(inputStreamReader); System.out.println(bufferedInputStream.readLine()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } 复制代码
readLine的本身的意义不是一行读,他会额外读一些内容到自己内部,它本身的意思是增加缓冲,他会额外读一些内容到缓冲
从BufferReader 源码可以看出:
private static int defaultCharbufferSize = 8192 复制代码
默认可以读 8192 个字节,为了提高性能,我们必须设置一个默认值
Buffer 写数据 其实是在缓冲里面放数据,所以写完之后记得及时 flush 将目标东西刷新到目标区
try (OutputStream sFileInputStream = new FileOutputStream("./24_io/24_io.txt")) { final BufferedOutputStream inputStream = new BufferedOutputStream(sFileInputStream); inputStream.write('a'); inputStream.write('b'); inputStream.write('M'); inputStream.flush(); } catch (Exception e) { e.printStackTrace(); } 复制代码
如: outPutStream 没有 flush 不会写成功的,那么为什么Buffer不能自动刷新呢?
因为缓冲是为了做效率, 和文件操作性能会比较低,所以尽量减少这样的操作,把频率降低,把多次io给合起来,这样才能提高性能呢.Buffer 会导致输出不同步这是必然的事情
同样在 try 里面 做数据包装操作,也会自动刷新缓存到目标区
try (OutputStream sFileInputStream = new FileOutputStream("./24_io/24_io.txt"); final BufferedOutputStream inputStream = new BufferedOutputStream(sFileInputStream)) { inputStream.write('a'); inputStream.write('b'); inputStream.write('M'); } catch (Exception e) { e.printStackTrace(); } 复制代码
文件复制
java没有文件复制的功能的,那么怎么做文件复制呢,我们要做的是把文件数据一个一个搬
try (InputStream fileInputStream = new FileInputStream("./24_io/24_io.txt"); OutputStream outputstream = new FileOutputStream("./24_io/text_copy.txt")) { final byte[] bytes = new byte[1024]; int read = 0; while ((read = fileInputStream.read(bytes)) != -1) { outputstream.write(bytes, 0, read); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } 复制代码
如果想提高性能 我们可以加 Buffer
这就是 Java 的 I/O 原理,核心就是:内存与外界的交互,你可以用 inputStream 和 outPutStream 做对接
Socket 和 ServerSocket 之间的网络交互
和文件交互是 java i/o 里面 和 网络进行交互的,就像和文件交互 用 File 比如: 我做个服务器
try { final ServerSocket serverSocket = new ServerSocket(8080); final Socket socket = serverSocket.accept(); final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); while (true) { final String data = reader.readLine(); writer.write("你给我输入了: " + data); writer.flush(); } } catch (IOException e) { e.printStackTrace(); } 复制代码
nio 与传统 io的区别
-
传统io用的是插管道的方式 
-
nio 的 Channel 是双向的,传统io是单向的
try { final RandomAccessFile file = new RandomAccessFile("./24_io/24_io.txt", "r"); final FileChannel channel = file.getChannel(); final ByteBuffer byteBuffer = ByteBuffer.allocate(1024); channel.read(byteBuffer); byteBuffer.flip(); System.out.println(Charset.defaultCharset().decode(byteBuffer)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } 复制代码
- nio 也用到了缓冲 buffer nio 可以被操作的,nio的Buffer是强制使用的,不好用
try { final ServerSocketChannel channel = ServerSocketChannel.open(); channel.bind(new InetSocketAddress(8080)); final SocketChannel socketChannel = channel.accept(); final ByteBuffer byteBuffer = ByteBuffer.allocate(1024); while (socketChannel.read(byteBuffer) != -1) { byteBuffer.flip(); socketChannel.write(byteBuffer); byteBuffer.clear(); } } catch (IOException e) { e.printStackTrace(); } 复制代码
- nio 有非阻塞的支持,只能网络才能使用
try { final ServerSocketChannel channel = ServerSocketChannel.open(); channel.bind(new InetSocketAddress(8080)); channel.configureBlocking(false); final SocketChannel socketChannel = channel.accept(); final ByteBuffer byteBuffer = ByteBuffer.allocate(1024); while (socketChannel.read(byteBuffer) != -1) { byteBuffer.flip(); socketChannel.write(byteBuffer); byteBuffer.clear(); } } catch (IOException e) { e.printStackTrace(); } 复制代码
为什么 非阻塞式 nio 设置 configureBlocking 开关 会报NullException?
Exception in thread "main" java.lang.NullPointerException 复制代码
因为 channel.accept() 没有拿到数据,socketChannel 为 null,还没有发起请求就设置 false了
okio
okio 作为一个外部对象作为输入输出,okio是独立形式存在的.
try (BufferedSource source = Okio.buffer(Okio.source(new File("./24_io/24_io.txt")) )) { final Buffer buffer = new Buffer(); source.read(buffer, 1024); System.out.println(buffer.readUtf8()); } catch (Exception e) { e.printStackTrace(); } 复制代码
okio 和 传统 io 作交互
final Buffer buffer = new Buffer(); try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(buffer.outputStream())); BufferedReader bufferReader = new BufferedReader(new InputStreamReader(buffer.inputStream()))) { writer.write("哈哈哈哈"); writer.flush(); System.out.println("read: " + bufferReader.readLine()); } catch (IOException e) { e.printStackTrace(); } 复制代码
以上所述就是小编给大家介绍的《Java I/O 和 oKio》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Docker——容器与容器云
浙江大学SEL实验室 / 人民邮电出版社 / 2015-9-1 / 89.00元
本书从实践者的角度,在讲解Docker高级实践技巧的同时,深入到源代码层次,为读者梳理出Docker容器技术和基于Docker的容器云技术(如Kubernetes)的实现方法和设计思路,帮助读者理解如何在实际场景中利用Docker解决问题并启发新的思考。全书包括两部分,第一部分深入解读Docker容器技术,包括Docker入门、架构总览、Docker容器核心原理解读,以及Docker高级实践技巧;......一起来看看 《Docker——容器与容器云》 这本书的介绍吧!