zoukankan      html  css  js  c++  java
  • 深入Java网络编程与NIO(二)

    Java IO流总结

    Java IO类图

    • 按照操作方式分类:
      Java IO类图

    Java IO按照操作单元分,可以分为字节流InputStream、OutputStream和字符流Reader、Writer

    • 字节流和字符流的区别:
      字节流在JDK1.0中就被引进了,用于操作包含ASCII字符的文件。JAVA也支持其他的字符如Unicode,为了读取包含Unicode字符的文件,JAVA语言设计者在JDK1.1中引入了字符流。ASCII作为Unicode的子集,对于英语字符的文件,可以可以使用字节流也可以使用字符流。

    • 按照操作对象分类
      Java IO类图2

    • 总结:
      Java IO这样设计的原因是让每一个类都负责不同的功能。共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系,
      Java IO流的40多个类都是从如下4个抽象类基类中派生出来的。

    InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
    OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

    Java IO

    1.文件IO

    JAVA 中文件IO原生的读写方式大概可以被分为三种:普通IO,FileChannel(文件通道),MMAP(内存映射)。区分他们也很简单,例如 FileWriter,FileReader 存在于 java.io 包中,他们属于普通IO;FileChannel 存在于 java.nio 包中,属于 NIO 的一种,但是注意 NIO 并不一定意味着非阻塞,这里的 FileChannel 就是阻塞的;较为特殊的是后者 MMAP,它是由 FileChannel 调用 map 方法衍生出来的一种特殊读写文件的方式,被称之为内存映射。

    FileChannel 和 MMAP

    使用 FIleChannel 的方式:

    FileChannel fileChannel = new RandomAccessFile(new File("db.data"), "rw").getChannel();
    

    获取 MMAP 的方式:

    MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileChannel.size()
    );
    

    FileChannel 大多数时候是和 ByteBuffer 这个类打交道,你可以将它理解为一个 byte[] 的封装类,提供了丰富的 API 去操作字节,不了解的同学可以去熟悉下它的 API。值得一提的是,write 和 read 方法均是线程安全的,FileChannel 内部通过一把 privatefinalObjectpositionLock=newObject(); 锁来控制并发。

    一个问题:FileChannel 是直接把 ByteBuffer 中的数据写入到磁盘吗?
    思考几秒…答案是:NO。
    ByteBuffer 中的数据和磁盘中的数据还隔了一层,这一层便是 PageCache,是用户内存和磁盘之间的一层缓存。我们都知道磁盘 IO 和内存 IO 的速度可是相差了好几个数量级。我们可以认为 filechannel.write 写入 PageCache 便是完成了落盘操作,但实际上,操作系统最终帮我们完成了 PageCache 到磁盘的最终写入,所以 FileChannel 会提供一个 force() 方法,用于通知操作系统进行及时的刷盘。
    所以,当我们使用 FileChannel 进行读操作时,同样经历了:磁盘->PageCache->用户内存这三个阶段。

    MMAP
    MMAP 的作用:内存映射文件,我们之后对内存中 MappedByteBuffer 做的任何操作,都会被最终映射到文件之中,

    mmap 把文件映射到用户空间里的虚拟内存,省去了从内核缓冲区复制到用户空间的过程,文件中的位置
    在虚拟内存中有了对应的地址,可以像操作内存一样操作这个文件,相当于已经把整个文件放入内存,但在
    真正使用到这些数据前却不会消耗物理内存,也不会有读写磁盘的操作,只有真正使用这些数据时,也就是
    图像准备渲染在屏幕上时,虚拟内存管理系统 VMS 才根据缺页加载的机制从磁盘加载对应的数据块到物理
    内存进行渲染。这样的文件读写文件方式少了数据从内核缓存到用户空间的拷贝,效率很高

    MMAP 操作大文件性能比 FileChannel 搞出一个数量级!

    参考资料:

    Java IO常见面试题
    文件IO操作的最佳实践

  • 相关阅读:
    AD域渗透总结
    CTF
    ew做代理 进一步内网渗透
    CVE-2019-0708复现
    win 内网frp反弹到内网liunx
    Liunx反弹shell的几种方式
    sql到python正则
    PHP面向对象学习-属性 类常量 类的自动加载 构造函数和析构函数 访问控制(可见性)
    PHP反序列化学习
    PHP面向对象学习
  • 原文地址:https://www.cnblogs.com/shawshawwan/p/10104493.html
Copyright © 2011-2022 走看看