当前位置: 首页 > 后端技术 > Java

biang崽学习java——大杂烩(2)——io

时间:2023-04-01 23:33:58 Java

java.io位于java.base包下。需要查阅jdk文档。之前有个简单的总结,这里大致说一下初步了解java.io的感受。当前摘要将涵盖最后一部分。那么可能文章偏向于整体的理解,然后具体到java。1.io概念/知识io:输入&输出。输入设备输入,输出设备输出。涉及计算机核心和其他设备的数据迁移过程都是io。包括:磁盘IO:从磁盘读取数据,向磁盘写入数据。其他外设IO:写数据到网卡(发送到远程主机/服务器)、显示器、硬盘...IO实现过程:【因为需要外部设备来防止用户进程不安全,所以操作系统需要usesystemcallstoassistImplementation]应用程序向操作系统发起IO调用。操作系统等待io设备就绪,并将数据从外部设备加载到内核缓冲区中。【或者将用户进程的数据复制到内核】将内核缓冲区的数据复制到用户进程缓冲区。【将内核的数据复制到外部设备】接下来需要说明一下,java.io下有几个问题需要讨论:我也觉得这些是稍微学了一点的题目的内容。如有其他补充或见解欢迎交流java.io类分析序列化/反序列化io模型2.java.io类分析前面提到java.io包在java.base【javaSE函数API模块】java.io。java.base(JavaSE18&JDK18)分类java.io按读取单位大小可分为:字节流[读取单位:字节]、字符流[读取单位:字符{中文:2个字节,英文:1byte}]按方向可分为:输入流和输出流。因为读取数据的类型不同或者除了完成必要的读写功能之外还想增加一些功能,或者提高效率或者加解密,可以细分出很多封装好的io类,这些类被称为装饰流。而Filter_X是很多装饰类的父类,但是字符流和字节流装饰类的继承是不一样的。字符流直接继承了read/write,字节流继承了Filter_X,但实际上Filter_X也继承了input/outputStream。查看文件树,缩进代表继承关系。稍微区分一下不同装饰流的作用:3.序列化和反序列化是对象的一个??概念。1)概念序列化:将一个java对象变成一个二进制内容[字节数组]反序列化:将一个二进制内容变成一个java对象。2)这样做的原因是对象需要保存在本地。因为java对象的生命周期在程序结束后就结束了,它就会被销毁,而我们又想将它持久化到磁盘或者数据库中。通过网络传输对象,比如使用RPC框架,用户需要从服务器获取javabean对象,然后调用它的方法/获取它的属性。对象需要转换为二进制以便通过网络传输。3)Use方法一个对象要被序列化:这个对象的所有属性(私有属性、protected、public及其引用的对象)都可以被序列化并保存/传递。有2个接口可以用来实现序列化:SerializbleExternalizableSerializble实现方法:wirteObject()readObject()ps:1.如果有某个属性不想实现序列化:修改属性为transient。[具体用法可参考]2.静态成员变量不能序列化。3、需要显示声明serialVersionUID【控件序列化版本】。如果没有显式生成,系统会根据生成的输入自动生成serialVersionUID:类名、类及其属性修饰符、接口及接口顺序、属性、静态初始化、构造函数。可以控制不同版本的类拥有相同的serialVersionUID,实现不同版本的序列化兼容。可以控制不同版本的类有不同的serialVersionUID。反序列化时,对新增的字段填默认值null,减少的字段直接忽略。Externalizableserializable的子类。实现方法:wirteExternal()readExternal()ps:1.可以指定序列化哪些属性。2.反序列化时,首先调用类的无参构造函数。[所以如果无参构造函数被删除/或者无参构造函数被设置为private、default或protected级别,将会产生异常:java.io.InvalidException:novalidconstructorexception]4)需要注意的问题在序列化中a.Serialization打破了单例模式单例模式:充分发挥作用,一个对象只有一个实例,没有副本。序列化如何破坏单例模式:序列化一个对象,然后反序列化该对象得到一个新的对象。readObject()使用反射技术调用无参数构造函数来创建新对象。解决方案:在需要单例的对象类中添加代码:b.序列化不安全在网络上传输对象的序列化二进制数据时,所有字段(包括private)的数据都会以明文二进制的形式出现,在网络传输过程中,很容易被截获并发现数据内容。解决方案序列化/挂钩(移位/重置)。序列数据加密/签名。使用瞬态。[transient修饰的变量反序列化后显示为null[readObject]]打包解包代理。5)序列化和反序列化的底层原理【需要继续看源码】4.IO模型1)同步的几个概念:调用发起后,如果调用没有处理,会一直卡住,不会回来。【不能一直执行其他任务,必须等待结果】异步:发起调用后,不需要获取返回结果,可以等待后续的事件、回调等机制来通知事件已经完成。您可以发送另一个请求。【可以做点别的,等通知工作解决】阻塞:在调用结果返回之前,线程被挂起,直到得到结果才会继续执行。[Donothing][eg:BIO,socket]非阻塞:调用不会阻塞当前线程,直到不能立即得到结果。【可以继续工作了】2)IO模型BIO的发展:同步阻塞发起io请求-等待数据准备好【线程挂起】-返回结果继续执行操作。可以使用多线程来并行提高处理效率。——>但是当发生高并发访问时,不能无限创建线程,线程消耗过多资源直至耗尽,导致服务器宕机。————>使用线程池可以限制线程数,避免服务器宕机,但还是不能处理高并发问题。当有多个请求时,如果访问者和都持有线程不释放,会导致后续访问无限等待。NIO:同步非阻塞【java1.4】发起IO请求-非阻塞,不断轮询数据是否就绪-处理完成,成功返回。3个核心组件:1.buffer:读写数据,直接操作buffer。而不是从流中一个一个地读取数据。2.channel:双向通道,与buffer交互。3.selector:单线程选择channel,避免线程切换的开销。监视文件描述符的就绪状态,当状态变为可读时发起系统调用。1)监控io数量限制max:1024[linux];2)监听到io就绪后,遍历找到就绪的文件描述符。——>poll:解决连接数限制问题。还是遍历寻找文件描述符。AIO:asynchronousnon-blocking[java7]InitiateIO——注册事件,listen——IO就绪——通知进程进行后续操作。epoll多路复用机制:1.epoll_ctl注册文件描述符,加入监听。2.当文件描述符就绪时,内核回调激活文件描述符。3.进程调用epoll_wait得到通知。