• java高级---IO流


    目录

    分类:

    流动方向:(数据的传入方向)

    数据形式:

    流的作用:

    装换字节与字符流的特殊流:转换流

    InputStream & Reader

    装饰流:(缓冲流)

    字符流:

    字符输入流:

    字符输出流:

    转换流:

    InputStreamReader

    OutputStreamWriter

    对象流:

    序列化对象

    反序列化对象

    JDK7的新特性:

    try -with -resources

    当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。

    当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。

    因此我们把这种输入和输出动作称为IO操作。数据在内存中的流动;

    广义上来讲:不同电脑之间数据的流动,也是IO流

    狭义上的IO操作:进程之间的数据流动

    分类:

    流动方向:(数据的传入方向)

    • 输入流 (InputStream)/(Reader)

    • 输出流 (OutputStream)/(Writer)

    数据形式:

    • 字节流(二进制的形式)(InputStream / OutputStream)

    • 字符流(以字符的形式)

    流的作用:

    • 节点流

    • 装饰流(过滤流)

    装换字节与字符流的特殊流:转换流

    InputStream & Reader

    InputStream 和 Reader 是所有输入流的基类。

    InputStream(典型实现:FileInputStream)

    int read() ----一次读完

    int read(byte[] b) ----读到字节数组中

    int read(byte[] b, int off, int len)

    Reader(典型实现:FileReader)

    int read()

    int read(char [] c)

    int read(char [] c, int off, int len)

    程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资 源,所以应该显式关闭文件 IO 资源。 FileInputStream 从文件系统中的某个文件中获得输入字节。FileInputStream 用于读取非文本数据之类的原始字节流。要读取字符流,需要使用 FileReader

    装饰流:(缓冲流)

     为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类 时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。

     缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:

    BufferedInputStream 和 BufferedOutputStream BufferedReader 和 BufferedWriter

    当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲  当使用BufferedInputStream读取字节文件。BufferedInputStream会一次性从 文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中 读取下一个8192个字节数组。

     向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法 flush()可以强制将缓冲区的内容全部写入输出流

     关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也 会相应关闭内层节点流

     flush()方法的使用:手动将buffer中内容写入文件

     如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷 新缓冲区,关闭后不能再写出

    字符流:

    针对可以识别的字符串,就可以使用字符流读取(加快流的操作而设计的,专门操作字符串)

    字符流存在编码问题,需要保证读取与写入时保持一致;

    字符输入流:

     int read() 读取单个字符。作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff)(2个 字节的Unicode码),如果已到达流的末尾,则返回 -1

     int read(char[] cbuf) 将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。

     int read(char[] cbuf,int off,int len) 将字符读入数组的某一部分。存到数组cbuf中,从off处开始存储,最多读len个字 符。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。

     public void close() throws IOException 关闭此输入流并释放与该流关联的所有系统资源。

    整行读,建议使用打印输出流!!!

    字符输出流:

     void write(int c) 写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。 即 写入0 到 65535 之间的Unicode码。

     void write(char[] cbuf) 写入字符数组。

     void write(char[] cbuf,int off,int len) 写入字符数组的某一部分。从off开始,写入len个字符  void write(String str) 写入字符串。

     void write(String str,int off,int len) 写入字符串的某一部分。

     void flush() 刷新该流的缓冲,则立即将它们写入预期目标。

     public void close() throws IOException 关闭此输出流并释放与该流关联的所有系统资源。

    转换流:

    转换流提供了在字节流和字符流之间的转换

    Java API提供了两个转换流:

    • InputStreamReader:将InputStream转换为Reader

    • OutputStreamWriter:将Writer转换为OutputStream  字节流中的数据都是字符时,转成字符流操作更高效。  很多时候我们使用转换流来处理文件乱码问题。实现编码和 解码的功能。

    InputStreamReader

     实现将字节的输入流按指定字符集转换为字符的输入流

     需要和InputStream“套接”。

     构造器  public InputStreamReader(InputStream in)

     public InputSreamReader(InputStream in,String charsetName) 如: Reader isr = new InputStreamReader(System.in,”gbk”); 指定字符集

    OutputStreamWriter

     实现将字符的输出流按指定字符集转换为字节的输出流。

     需要和OutputStream“套接”。

     构造器

     public OutputStreamWriter(OutputStream out)

     public OutputSreamWriter(OutputStream out,String charsetName)

     

    对象流:

    ObjectInputStream和OjbectOutputSteam

    用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中也能把对象从数据源中还原回来。

    序列化:用ObjectOutputStream类保存基本类型数据或对象的机制

    反序列化:用ObjectInputStream类读取基本类型数据或对象的机制

    ObjectOutputStream和ObjectInputStream不能序列化static和transient修 饰的成员变量

    对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从 而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传 输到另一个网络节点。//当其它程序获取了这种二进制流,就可以恢复成原 来的Java对象

    序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据, 使其在保存和传输时可被还原

    序列化是 RMI(Remote Method Invoke – 远程方法调用)过程的参数和返 回值都必须实现的机制,而 RMI 是 JavaEE 的基础。因此序列化机制是 JavaEE 平台的基础

    如果需要让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一。 否则,会抛出NotSerializableException异常 (对象不支持序列化的异常)

    • Serializable

    • Externalizable

    凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量

    • private static final long serialVersionUID;

    • serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象 进行版本控制,有关各版本反序列化时是否兼容。

    • 如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自 动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议, 显式声明。

     简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验 证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的 serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同 就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

    序列化对象

    将虚拟的对象转化为可以直接传输或者保存到数据的过程;(官方提供的序列化是将对象转化为字节)

    若某个类实现了 Serializable 接口,该类的对象就是可序列化的:

    创建一个 ObjectOutputStream

    调用 ObjectOutputStream 对象的 writeObject(对象) 方法输出可序列化对象

    注意写出一次,操作flush()一次

    反序列化对象

    将序列化的字节或者字符重新转化为对象的过程;

    创建一个 ObjectInputStream

    调用 readObject() 方法读取流中的对象

    强调:如果某个类的属性不是基本数据类型或 String 类型,而是另一个 引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的 Field 的类也不能序列化

    注意:transient(转瞬即逝的)修饰的变量不能序列化(持久化)!!!

    JDK7的新特性:

    try -with -resources

    帮助程序员,防止忘记关闭资源 ------(新的关闭流答操作)

    1. try(打开需要关闭的资源){
    2. }catch{
    3. }

    在开发过程中,如果直接将一些确定的值,写在代码中,代码的设计可能有问题如果生产环境中,要再次修改值,发现非常麻烦,需要重新编译这种编程,叫做硬编码

    开发环境:( development environment)

    测试环境:(test environment )

    生产环境:( product environment )

    • 如果值永久不变:

    做成常量

    做成枚举

    • 如果有可能变:

    可以做成配置文件

    配置文件:

    xml:

    json:

    yaml:(缩进表示不同的关系) ----前三种为独立的技术

    properties:Java的配置文件

  • 相关阅读:
    2023年国自然植物科学相关面上项目信息公布(小麦、大麦、棉花、大豆、玉米)
    冯诺依曼体系各硬件工作原理解析
    探索Maven创建项目全过程(超详细~~~)
    【AI】生成模型变得简单:了解它们的工作原理和不同类型
    【总】HEC-RAS学习记录
    python中那些常见的@装饰器
    git基本配置及代码下载上传
    PyQt5+SQLlite3基于邮箱验证的登陆注册找回系统
    ajax图书管理项目
    浙大版C语言题目集-函数题6
  • 原文地址:https://blog.csdn.net/qq_58029155/article/details/126331251