当前位置: 首页 > news >正文

Java 实训 十四天 IO流

Java IO流

一、转换流
1、定义
    将字节流转换为字符流(就是在字节流的基础上,增加编码器解码器)  
    
2、转换器
    InputStreamReader -》字节输入流转化为字符输入流
    构造:
        InputStreamReader(InputStream in)
        InputStreamReader(InputStream in, String charsetName)
    
    

    OutputStreamWriter -> 字节输出流转化为字符输出流
    构造:
        OutputStreamWriter(OutputStream out)
        OutputStreamWriter(OutputStream out, String charsetName)
    
    
    案例代码:自定义扫描器并实现readLine()方法
    class MyScanner{
        private InputStream in;

        public MyScanner(InputStream in) {
            this.in = in;
        }

        public String readLine() throws Exception{
            //将字节输入流转为字符输入流
            InputStreamReader inputStreamReader = new InputStreamReader(this.in);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            return bufferedReader.readLine();
        }

    }

二、PrintStream、PrintWriter

    这两个类也属于包装器的一种  
    PrintStream: 可以用于包装OutputStream  
    PrintWriter: 可以包装一个Writer

    
    包装后的对象可以调用相应的print方法实现在控制台打印输出:
    print();
    println();
    
    案例代码:通过打印流将内容打印到文件
    //指定打印的目标地址
        FileWriter fileWriter = new FileWriter("D:\\test\\content.txt");
        PrintWriter out = new PrintWriter(fileWriter, true);

        out.println("hello world");
        out.println("这是打印流");

三、Properties
1、定义
    Properties表示属性集,通常伴随以properties作为后缀的属性配置文件出现。
    在properties文件中,每一行都是一个配置项,并且是以键值对形式出现,例如:
    
    server.port=8080
    
2、构造方法
    Properties()
    Properties(Properties defaults)
    
3、常用方法
    Object setProperty(String key, String value)  //设置属性
    String getProperty(String key)  //获取属性
    void list(PrintStream out)
    void load(InputStream inStream) //载入属性文件
    void load(Reader reader)
    void store(OutputStream out, String comments) //存储
    void store(Writer writer, String comments)

4、操作案例
    //构建properties属性配置文件对象
    Properties properties = new Properties();

    //构建属性文件的字节输入流
    InputStream resourceAsStream = Day14Demo03.class.getClassLoader().getResourceAsStream("application.properties");
    //载入属性文件
    properties.load(resourceAsStream);

    //读取属性文件中的配置项
    String port = properties.getProperty("server.port");

    //修改服务器监听端口为80
    properties.setProperty("server.port", "80");


    //获取属性文件中的所有配置
    for (Map.Entry<Object, Object> entry:properties.entrySet()) {
        System.out.println(entry.getKey()+"---"+entry.getValue());
    }

    /*//修改完配置后需要重写属性文件
    //构造一个字节输出流
    FileOutputStream fileOutputStream = new FileOutputStream("D:\\Java\\workspace\\test\\resources\\application.properties");

    properties.store(fileOutputStream, "修改服务器的监听端口"); //将内存中已经修改好的属性内容重写到目标文件

    //关流
    fileOutputStream.close();
    resourceAsStream.close();*/
    

四、合并流
1、定义
    将多个打开流合并为一个。
    
2、类及构造
构造:
    SequenceInputStream(InputStream s1, InputStream s2)
    SequenceInputStream(Enumeration<? extends InputStream> e)


3、合并流案例
    Vector<InputStream> logs = new Vector<>();

    //创建日志1的输入流
    FileInputStream log1 = new FileInputStream(pathPre + "20240407-1.log");
    FileInputStream log2 = new FileInputStream(pathPre + "20240407-2.log");
    FileInputStream log3 = new FileInputStream(pathPre + "20240407-3.log");

    //添加准备合并的输入流
    logs.add(log1);
    logs.add(log2);
    logs.add(log3);

    //InputStream sequenceInputStream = new SequenceInputStream(log1, log2);

    SequenceInputStream sequenceInputStream = new SequenceInputStream(logs.elements());

    //转换流
    InputStreamReader inputStreamReader = new InputStreamReader(sequenceInputStream);

    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

    while (true){
        String msg = bufferedReader.readLine();
        if (Objects.isNull(msg)){
            break;
        }
        System.out.println(msg);

    }


练习:将如下多个文件中的学生报道信息通过合并流读取并提取时间,姓名和地址。输出到控制台
students-info1.txt
    [2023-6-15] 张三 16 成都
    [2023-6-26] 李四 21 绵阳

students-info2.txt
    [2023-9-1] 王五 19 宜宾
    [2023-9-10] 赵六 20 广州
    
students-info3.txt
    [2023-11-06] 田七 18 上海
    [2023-12-11] 猪八 18 西昌
    

五、其他IO流

1、ByteArrayInputStream、ByteArrayOutputStream
    目的地是一个可变长度的字节数组的字节输入流、字节输出流 -- 目的地是内存的字节流  

    构造:
        ByteArrayOutputStream()
        
    方法:
        void write(int b)
        void write(byte[] b, int off, int len)
        byte[] toByteArray()

2、StringReader、StringWriter
    StringWriter 目的地是一个字符串的输出流
    StringReader 数据的来源是一个字符串的输入流


六、对象序列化/反序列化

序列化(钝化):
1、定义
    ObjectOutputStream 将内存中的对象序列化到流中
    
2、类信息
    构造方法:
        ObjectOutputStream(OutputStream out)

    方法:
        void writeObject(Object obj)
        
    注意:
        如果对象需要序列化,则对应的类必须实现Serializable接口!
    

案例代码:将Student对象序列化到本地文件中
    String path = "D:\\test\\logs\\Student.txt";

    //实例化对象
    Student student = new Student("张三", 18, "成都", "15698457412");

    //构造文件输出流
    FileOutputStream fileOutputStream = new FileOutputStream(path);

    //序列化
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

    objectOutputStream.writeObject(student);

    objectOutputStream.close();
    fileOutputStream.close();    

反序列化(活化):
1、定义
    ObjectInputStream 可以将流中的序列化的对象信息反序列化为对象
    

2、类信息
    构造方法:
        ObjectInputStream(InputStream in)
    
    方法:
        Object readObject()

案例代码:将Student序列化后的文件,反序列化为对象
    String path = "D:\\test\\logs\\Student.txt";

    //转化为输入流
    FileInputStream fileInputStream = new FileInputStream(path);

    //反序列化
    ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

    Student student = (Student) objectInputStream.readObject();

    //打印对象信息
    System.out.println(student);

    
总结:
    * 静态成员不能被序列化
    * transient修饰的成员会被忽略
    * 被Serializable接口修饰的类在被编译为.class时会被标记一个独一无二的serialVersionUID,
    利用这个id在反序列化时进行检查,保证只有完全一致的类才能反序列化,从而保证安全性。
    * 我们也可以自己定义serialVersionUID,从而自己控制序列化和反序列化的安全检查,实现,
    在类只有轻微改动的情况下,仍然可以实现反序列化的功能。 


 


http://www.mrgr.cn/news/67724.html

相关文章:

  • 跟《经济学人》学英文:2024年11月02日这期 Too many people want to be social-media influencers
  • 使用k8s RBAC和ValidatingAdmissionPolicy 配合来校验用户权限
  • UE hard/soft reference| DDX DDY | Unity pcg color
  • InsCode线上IDE推荐及使用指南
  • Linux LCD屏幕亮度自动调节
  • 【MyBatis源码】CacheKey缓存键的原理分析
  • 对称二叉树(力扣101)
  • 国标GB28181
  • 一台电脑如何同时多开多 IP 浏览器多登账号?
  • git中的gitignore文件
  • 大模型-微调与对齐-人类对齐背景与标准
  • 【Linux】冯诺依曼体系、再谈操作系统
  • 使用Postman搞定各种接口token实战
  • 自动驾驶革命:从特斯拉到百度,谁将主宰未来交通?
  • hcitool命令和bluetoothctl命令
  • linux文件重命名
  • HTB:Nibbles[WriteUP]
  • 实战:Python+ Flask轻松实现Mock Server
  • 【AD】3-1 原理图页的大小及自定义设置
  • 构建可视化站点地图:提升用户体验
  • Oracle 迁移到 OB 过程中的函数改造案例
  • AP5001A AP系列模拟信号源
  • 标签权重的计算方法之贝叶斯平滑
  • Postman上传图片如何处理
  • M1M2 MAC安装windows11 虚拟机的全过程
  • Oracle 数据库特性一图快速了解