Java SE 学习笔记(十四)—— IO流(3)

news2024/9/24 1:17:47

目录

  • 1 缓冲流
    • 1.1 缓冲流概述
    • 1.2 字节缓冲流
    • 1.3 字符缓冲流
  • 2 转换流
    • 2.1 字符输入转换流
    • 2.1 字符输出转换流
  • 3 序列化
    • 3.1 对象序列化
    • 3.2 对象反序列化
  • 4 打印流
  • 5 与Properties结合使用
  • 6 IO 框架

1 缓冲流

1.1 缓冲流概述


我们之前学习的字节流、字符流属于基础流、原始流,性能其实不是最好的,缓冲流读写数据的性能更好

在这里插入图片描述

缓冲流也称为高效流、高级流,其自带缓冲区,可以提高原始字节流、字符流读写数据的性能。功能上并无很大变化,性能提升了。

1.2 字节缓冲流


字节缓冲输入流:

  • BufferedInputStream ,提高字节输入流读取数据的性能。
  • 字节缓冲输入流自带了 8KB 缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。

字节缓冲输出流:

  • BufferedOutputStream ,提高字节输出流读取数据的性能。
  • 字节缓冲输出流自带了 8KB 缓冲池,数据就直接写入到缓冲池中去,写数据性能极高了。

构造方法

在这里插入图片描述

为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?

  • 字节缓冲流仅仅提供缓冲区,而真正读写数据还是得依靠基本的字节流对象进行操作

1.3 字符缓冲流


符缓冲输入流:

  • BufferedReader,提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能。

在这里插入图片描述
在这里插入图片描述

字符缓冲输出流:

  • BufferedWriter ,提高字符输出流写取数据的性能,除此之外多了换行功能

在这里插入图片描述

在这里插入图片描述

示例代码:

import java.io.*;

public class Test1 {
    public static void main(String[] args) throws IOException {
        FileWriter f1 = new FileWriter("D:\\StudyTools\\test.txt");
        BufferedWriter bw = new BufferedWriter(f1);

        bw.write("我");
        bw.write("abc");
        bw.newLine();
        bw.write("hhhh");
        bw.close(); // 字符首先写到缓冲池,关闭文件后刷新,写入的文件有内容显示

        FileReader f2 = new FileReader("D:\\StudyTools\\test.txt");
        BufferedReader br = new BufferedReader(f2);
        System.out.println(br.readLine()); // 我abc
        System.out.println(br.readLine()); // hhhh
        System.out.println(br.readLine()); // null
    }
}

推荐使用哪种方式提高字节流读写数据的性能?

  • 建议使用字节缓冲输入流、字节缓冲输出流,结合字节数组的方式, 目前来看是性能最优的组合。

2 转换流


使用字符流读取中文不会乱码,那如果读取的文件编码与代码编码不一致怎么办呢?

在这里插入图片描述

2.1 字符输入转换流


针对文件编码与代码编码不一致导致的乱码问题,如何解决?

  • 使用字符输入转换流
    • 可以提取文件的原始字节流(原始字节不会存在问题)
    • 然后把字节流以指定编码转换成字符输入流(这样字符输入流的字符就不会乱码了)

字符输入转换流: InputStreamReader ,可以把原始的字节流按照指定编码转换成字符输入流。

在这里插入图片描述

示例代码:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/*
* 代码是UTF-8,文件是GBK
* */
public class Test1 {
    public static void main(String[] args) throws IOException {
        // 1. 提取字节码文件的原始字节流
        FileInputStream f = new FileInputStream("D:\\StudyTools\\test.txt");
        // 2. 把原始字节流转换为字符输入流
//        InputStreamReader isr = new InputStreamReader(f); // 默认UTF-8转换字符流还是会乱码
        InputStreamReader isr = new InputStreamReader(f,"GBK");
        BufferedReader br = new BufferedReader(isr);
        String s;
        while((s=br.readLine())!=null){
            System.out.println(s);
        }
    }
}

2.1 字符输出转换流


如果需要控制写出去的字符使用的编码,怎么办?

  • 可以把字符以指定编码获取字节后再使用字节输出流写出去
    • "我爱你中国" .getBytes(编码)
  • 也可以使用字符输出转换流实现

字符输出转换流: OutputStreamWriter ,可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码

在这里插入图片描述

示例代码:

import java.io.*;

/*  代码是UTF-8
    指定写出去文件的字符编码GBK
* */

public class Test {
    public static void main(String[] args) throws IOException {
        // 1. 定义一个字节输出流
        FileOutputStream os = new FileOutputStream("io/src/out.txt");
        // 2. 把原始的字节输出流转换成字符输出流
        OutputStreamWriter osw = new OutputStreamWriter(os,"GBK");
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write("123我爱你中国");
        bw.write("123我爱你中国");
        bw.newLine();
        bw.write("123我爱你中国");
        bw.close();
    }
}

3 序列化


如何把Java对象进行长久的保存?

在这里插入图片描述

3.1 对象序列化


对象序列化:

  • 以内存为基准,把内存中的对象存储到磁盘文件中去。
  • 使用到的流是对象字节输出流ObjectOutputStream

构造方法

在这里插入图片描述

序列化方法

在这里插入图片描述

示例代码

学生对象

import java.io.Serializable;

public class Student implements Serializable {
	// 声明序列化的版本号
    private static final long serialVerionUID=1;
    private int age;
    private String name;
    private String passwd;
    // private transient String passwd; // 表示修饰的成员变量不参与序列化

    public Student() {
    }

    public Student(int age, String name, String passwd) {
        this.age = age;
        this.name = name;
        this.passwd = passwd;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", passwd='" + passwd + '\'' +
                '}';
    }
}

序列化

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test {
    public static void main(String[] args) throws IOException {
        // 1. 创建学生对象
        Student s = new Student(18, "小明", "123123");
        // 2. 对象序列化
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io/src/obj.txt"));
        // 3. 调用序列化方法
        oos.writeObject(s);
        oos.close();
    }
}

注意:

  • 对象如果要序列化,必须实现 Serializable接口
    • 一个标记性接口,里面没有任何的抽象方法(实现一个接口就要实现里面所有的抽象方法)只要一个类实现了这个Serializable接口,那么就表示这个类的对象可以被序列化。
    • 实现该接口,不需要重写任何方法
  • transien修饰的成员变量不参与序列化
  • 序列化与反序列化的版本号必须一致

3.2 对象反序列化


对象反序列化:

  • 以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象
  • 使用到的流是对象字节输入流ObjectInputStream

构造方法

在这里插入图片描述

反序列方法

在这里插入图片描述

示例代码

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 1. 对象反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io/src/obj.txt"));
        // 2. 调用反序列化方法
        Student s = (Student)ois.readObject();
        System.out.println(s);
        ois.close();
    }
}

4 打印流


开发中有一种使用极为方便,性能高效的写数据的流,使用的很多。

打印流可以实现方便高效的打印数据到文件中去。打印流一般是指: PrintStreamPrintWriter 两个类。

可以实现打印什么数据就是什么数据,例如打印整数 97 写出去就是 97 ,打印 boolean 的 true ,写出去就是 true 。

构造方法

在这里插入图片描述

在这里插入图片描述

打印方法(二者一样)

在这里插入图片描述

示例代码

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class printDemo {
    public static void main(String[] args) throws FileNotFoundException {
        // 创建一个打印流对象
//        PrintStream ps = new PrintStream("io/src/ps.txt");
//        PrintStream ps = new PrintStream(new File("io/src/ps.txt"));
        PrintStream ps = new PrintStream(new FileOutputStream("io/src/ps.txt"));// 如果要追加数据,在低级管道后面加true

        ps.println(true);
        ps.println("我爱你中国");
        ps.println(123);
        ps.close();
    }
}

PrintStreamPrintWriter 的区别

  • 打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势)
  • PrintStream 继承自字节输出流 OutputStream ,支持写字节数据的方法。
  • PrintWriter 继承自字符输出流 Writer ,支持写字符数据出去。

输出语句重定向:属于打印流的一种应用,可以把输出语句的打印位置改到文件

import java.io.FileNotFoundException;
import java.io.PrintStream;

public class printDemo {
    public static void main(String[] args) throws FileNotFoundException {
        // 控制台打印
        System.out.println("床前明月光,");
        System.out.println("疑是地上霜。");
        // 改变输出语句的位置(将以下两句输出到文件)
        PrintStream ps = new PrintStream("io/src/print.txt");
        System.setOut(ps);
        System.out.println("举头望明月,");
        System.out.println("低头思故乡。");
    }
}

5 与Properties结合使用


Properties 集合是一个Map体系的集合类,但是一般我们不会当集合使用,因为HashMap更好用,其可以保存到流中或从流中加载。

Properties核心作用Properties 代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。

  • 属性文件:后缀是 .properties 结尾的文件 , 里面的内容都是 key=value ,后续做系统配置信息的。(那么这就涉及到文件内容的读写了,结合IO流)

Properties 和 IO 流结合的方法:

在这里插入图片描述

示例代码:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class PropertiesDemo {
    public static void main(String[] args) throws IOException {
        // 1. 使用Properties将键值对信息保存到属性文件中去(写)
//        Properties p = new Properties();
//        p.setProperty("admin","123456");
//        p.setProperty("huwei","000000");
//        p.setProperty("anni","888888");
//        p.store(new FileWriter("io/src/users.properties"),"这是备注信息");

        // 2. Properties读取属性文件中的属性信息(读)
        Properties properties = new Properties();
        System.out.println(properties);
        // 加载属性文件中的键值对数据到属性对象properties中去
        properties.load(new FileReader("io/src/users.properties"));
        System.out.println(properties);
 		// 获取属性值
        String rs1 = properties.getProperty("admin");
        System.out.println(rs1); // 123456
    }
}

6 IO 框架


commons-io 是 apache 开源基金组织提供的一组有关 IO 操作的类库,可以提高 IO 功能开发的效率。commons-io 工具包提供了很多有关 io 操作的类。有两个主要的类 FileUtilsIOUtils

FileUtils 主要有如下方法:

在这里插入图片描述

导入 commons-io-2.15.0.jar ,用其简化 IO 流读写

  • 在项目中创建一个文件夹 lib
  • commons-io-2.15.0.jar文件复制到 lib 文件夹
  • 在 jar 文件上点击右键,选择Add as Library,点击OK
  • 在类中导包使用

示例代码

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.*;

public class CommonsDemo {
    public static void main(String[] args) throws IOException {
        // 文件的复制
        IOUtils.copy(new FileInputStream("io/src/ps.txt"), new FileOutputStream("io/src/ps_copy.txt"));
        // 文件复制到某个文件夹下
        FileUtils.copyFileToDirectory(new File("io/src/ps.txt"),new File("D:\\"));
        // 文件夹复制到某个文件夹下
        FileUtils.copyDirectoryToDirectory(new File("io/src"),new File("D:\\"));
        // 删除文件夹(有内容)
        FileUtils.deleteDirectory(new File("D:\\src"));
        // 删除文件
        FileUtils.delete(new File("D:\\ps.txt"));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1143558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

引流大法,助你销量翻倍!亚马逊新卖家必备的六种流量来源!

作为亚马逊的一个新卖家,我们在新店上传产品之后,第一个目标就是引流,因为流量是支撑店铺销量的重要环节,那么我们引流的方式都有哪些呢? ​首先我们要知道亚马逊的一些流量来源分别有哪几块! 一、平台自…

计算机网络重点概念整理-第五章 传输层【期末复习|考研复习】

第五章 传输层 【期末复习|考研复习】 计算机网络系列文章传送门: 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 第五章 传输层 【期末复习|考研复习…

通过宏定义解决编程难题

大家好,我们今天来通过我们的define定义宏解决C语言上的难题。 实例一: offsetof这个宏我们在学习结构体的时候就已经了解过了,这个宏是我们在计算结构体大小的时候来查看每个结构体成员的偏移量的,那么我们在这里就来模拟实现一…

【LeetCode:2558. 从数量最多的堆取走礼物 | 大根堆】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

面试算法43:在完全二叉树中添加节点

题目 在完全二叉树中,除最后一层之外其他层的节点都是满的(第n层有2n-1个节点)。最后一层的节点可能不满,该层所有的节点尽可能向左边靠拢。例如,图7.3中的4棵二叉树均为完全二叉树。实现数据结构CBTInserter有如下3种…

线程状态,BLOCKED和WAITING 有什么区别

BLOCKED 和 WAITING 都是属于线程的阻塞等待状态。 BLOCKED BLOCKED 状态是指线程在等待监视器锁的时候的阻塞状态。 也就是在多个线程去竞争 Synchronized 同步锁的时候,没有竞争到锁资源的 线程,会被阻塞等待,这个时候线程状态就是 BLOCK…

众和策略:数据要素市场腾飞在即 游戏市场持续高增长

昨日,两市股指早盘弱势下探,午后沪指在银行、电力等板块的带动下发力拉升,深成指、创业板指均走高。到收盘,沪指涨0.48%报2988.3点,深成指涨0.4%报9566.1点,创业板指涨0.65%报1875.86点;两市合计…

[javaweb]——spring框架之控制反转(IOC)与依赖注入(DI)

🌈键盘敲烂,年薪30万🌈 目录 一、概念介绍 二、示例演示 2.1 代码高内聚问题 2.2 三层架构 2.3 分层解耦 2.4 分层解耦的实现 📕总结 一、概念介绍 控制反转:简称IOC,对象的创建控制权由程序自身转…

vulnhub_DeRPnStiNK靶机渗透测试

VulnHub2018_DeRPnStiNK靶机 https://www.vulnhub.com/entry/derpnstink-1,221/ flag1(52E37291AEDF6A46D7D0BB8A6312F4F9F1AA4975C248C3F0E008CBA09D6E9166) flag2(a7d355b26bda6bf1196ccffead0b2cf2b81f0a9de5b4876b44407f1dc07e51e6) flag4(49dca65f362fee401292ed7ada96f9…

人工智能基础_机器学习006_有监督机器学习_正规方程的公式推导_最小二乘法_凸函数的判定---人工智能工作笔记0046

我们来看一下公式的推导这部分比较难一些, 首先要记住公式,这个公式,不用自己理解,知道怎么用就行, 比如这个(mA)T 这个转置的关系要知道 然后我们看这个符号就是求X的导数,X导数的转置除以X的导数,就得到单位矩阵, 可以看到下面也是,各种X的导数,然后计算,得到对应的矩阵结…

ADI模数转换AD7091的SPI驱动接口verilog,代码/视频

名称:ADI模数转换AD7091的SPI驱动 软件:QuartusII 语言:Verilog 代码功能: 完成ADI单通道模数转换器AD7091R的逻辑接口设计。1 MSPS、超低功耗、12-Bit ADC (1)实现全部逻辑接口功能,完成对…

云端代码编辑器Atheos

什么是 Atheos ? Atheos是一个基于 Web 的 IDE 框架,占用空间小且要求最低,构建于 Codiad 之上,不过 Atheos 已从原始 Codiad 项目完全重写,以利用更现代的工具、更简洁的代码和更广泛的功能。 注意事项 群晖内核版本太…

系列二十、循环依赖(二)

一、请解释下Spring的三级缓存 所谓Spring的三级缓存是Spring内部解决循环依赖的三个Map,即DefaultSingletonBeanRegistry中的三个Map。 二、A、B两对象在三级缓存中的迁移过程 第一步:A创建过程中需要B,于是A将自己放到三级缓存里面&#x…

ubuntu安装nps客户端

Ubuntu安装nps客户端 1.什么是nps内网穿透?2.设备情况3.下载客户端3.链接服务端3.1、无配置文件模式3.2、注册到系统服务(启动启动、监控进程) 1.什么是nps内网穿透? nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发…

vue笔记(三)

15、过滤器 过滤器 用法:对要显示的数据进行特定格式化后再显示(用于一个简单的逻辑处理)语法 1、注册过滤器:Vue.fillter(name,callback) (全局)或 new Vue{filters:{}}(局部&…

Ubuntu20运行SegNeXt代码提取道路水体(四)——成功解决训练与推理自己的数据集iou为0的问题!!

在我的这篇博文里Ubuntu20运行SegNeXt代码提取道路水体(三)——SegNeXt训练与推理自己的数据集 经过一系列配置后 iou算出来是0 经过多次尝试后 终于让我试出来了正确配置方法! 具体的配置细节请查看这篇文章 1、在mmseg/datasets下面对数据集进行初始定义 我新建…

使用baostock获取上市公司情况

起因是有个不知道什么专业的同学问了我一题 cs: import baostock as bs import pandas as pd import datetime 日线指标参数包括:date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,peTTM,pbMRQ,psTTM,pcfNcfTTM,isST 周…

CompletableFuture的理解

CompletableFuture 是 JDK1.8 里面引入的一个基于事件驱动的异步回调类。简单来说,就是当使用异步线程去执行一个任务的时候,我们希望在任务结束以后触发一个后续的动作。而 CompletableFuture 就可以实现这个功能。 业务问题 举个简单的例子&#xff0…

最长公共子序列(LCS)与最长上升子序列(LIS)问题的相互转换

在此只做直观理解,不做严格证明 参考:LCS 问题与 LIS 问题的相互关系,以及 LIS 问题的最优解证明 LCS转LIS LCS转LIS只能对特殊情况适用。即当LCS中两个数组有一个不存在重复元素的情况下才能进行转换。 我们以一个例子进行说明&#xff0c…

leetCode 76. 最小覆盖子串 + 滑动窗口 + 哈希Hash

我的往期文章:此题的其他解法,感兴趣的话可以移步看一下: leetCode 76. 最小覆盖子串 滑动窗口 图解(详细)-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/134042115?spm1001.2014.3001.5501 力…