java IO流进阶操作

本文涉及的产品
RDS Agent(兼容OpenClaw),2核4GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 1.处理流(包装流)节点流是底层流/低级流,直接和数据源相连而处理流(包装流)包装节点流,即可以消除不用节点流的实现差异,也可以提供更方便的方法来完成输入输出操作可以认为,包装流是节点流的升级版本!💫包装流的两个优点:性能的提高:增加缓冲的方式来提高输入输出的效率操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便


1.处理流(包装流)


节点流是底层流/低级流,直接和数据源相连


而处理流(包装流)包装节点流,即可以消除不用节点流的实现差异,也可以提供更方便的方法来完成输入输出操作


可以认为,包装流是节点流的升级版本!💫


包装流的两个优点:


性能的提高:增加缓冲的方式来提高输入输出的效率

操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便


2.BufferedReader


BufferedReader常用于读取文本文件


使用示例:


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
 * 包装流
 * BufferedReader常用于读取文本文件
 * 包装流是节点流的升级版本
 */
public class BufferedReaderTest {
    public static void main(String[] args) throws IOException {
        String filePath = "D:\\hacker.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        String line;
        // 按行读取,效率高
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
        // 关闭流
        bufferedReader.close();
    }
}


3.BufferedWriter


很简单,代码示例:


/**
 * BufferedWriter演示
 */
public class BufferedWriterTest {
    public static void main(String[] args) throws IOException {
        String filePath = "D:\\hacker.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));
        bufferedWriter.write("大河");
        // 插入换行符
        bufferedWriter.newLine();
        bufferedWriter.write("之犬");
        bufferedWriter.close();
    }
}


4.Buffered字节处理流


程序示例:

拷贝图片


import java.io.*;
/**
 * Buffered字节处理流
 * 拷贝图片
 */
public class BufferedByteText {
    public static void main(String[] args) throws IOException {
        String srcFilePath = "D:\\xiao.jpg";
        String destFilePath = "D:\\cheng.jpg";
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(srcFilePath));
            bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
            byte[] buff = new byte[1024];
            int readLen = 0;
            // 循环读文件
            while ((readLen = bis.read(buff)) != -1) {
                // 边读边写
                bos.write(buff, 0, readLen);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            assert bis != null;
            bis.close();
            assert bos != null;
            bos.close();
        }
    }
}


5.对象处理流


Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。


将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。


整个过程都是 Java 虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。


类 ObjectInputStream 和 ObjectOutputStream 是高层次的数据流,它们包含反序列化和序列化对象的方法。


简单来说就是,序列化和反序列化:


序列化:保存值和数据类型

反序列化:恢复保存的值和数据类型

需要让某个对象支持序列化机制,需要保证该类是可序列化的:


该类必须实现以下两个接口之一:


Serializable(优先选择)

Externalizable

序列化演示:


/**
 * ObjectOutputStream进行序列化
 */
@Test
public void Out() throws IOException {
    String filePath = "D:\\data.dat";
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
    oos.write(100);
    oos.writeBoolean(true);
    oos.writeChar('a');
    oos.writeDouble(5.21);
    oos.writeUTF("IMUSTCTF");
    oos.writeObject(new Dog("旺财"));
    oos.close();
    System.out.println("数据序列化成功!");
}


反序列化演示:

dog类:


// Dog 需要实现Serializable接口才可以支持序列化操作
class Dog implements Serializable {
    private String name;
    private int age;
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


反序列化类:


/**
 * ObjectInputStream反序列化
 */
@Test
public void Input() throws IOException, ClassNotFoundException {
    String filePath = "D:\\data.dat";
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
    // 开始读取bat文件
    // 注意:读取顺序要和序列化时的顺序一致!
    System.out.println(ois.readInt());
    System.out.println(ois.readBoolean());
    System.out.println(ois.readChar());
    System.out.println(ois.readDouble());
    System.out.println(ois.readUTF());
    Object dog = ois.readObject();
    System.out.println(dog);
    // 访问dog的私有属性
    Dog dog1 = (Dog) dog;
    System.out.println(dog1.getName());
    // 关闭外层流
    ois.close();
}


对象处理流使用细节:🎈

  • 序列化的类要实现Serializable接口
  • 请按照序列化的顺序进行反序列化
  • 序列化的类中建议添加如下语句:(为了提高版本的兼容性)


@Serial
private static final long serialVersionUID = 1L;


序列化对象时,static和transient修饰的成员不会被序列化

序列化对象时,要求里面的属性也要实现序列化接口💫

序列化具有可继承性,父类实现了序列化,则其子类也会默认实现序列化🚲


6.转换流


InputStreamReader可以将InputStream字节流转换成Reader字符流


/**
 * InputStreamReader演示
 */
@Test
public void InputStreamReaderTest() throws IOException {
    String filePath = "D:\\hacker.txt";
    // FileInputStream转换为InputStreamReader
    InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), StandardCharsets.UTF_8);
    // 把InputStreamReader传入BufferedReader
    BufferedReader br = new BufferedReader(isr);
    String s = br.readLine();
    System.out.println(s);
    br.close();
}


OutputStreamWriter可以将OutputStream字节流转换成Writer字符流


/**
 * OutputStreamWriter
 */
@Test
public void OutputStreamWriterTest() throws IOException {
    String filePath = "D:\\hacker.txt";
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), "gbk");
    osw.write("hi,kiki!");
    osw.write("我是大河!");
    osw.close();
}


7.打印流


PrintStream是字节打印流,代码演示:


/**
 * 字节打印流
 */
@Test
public void PrintStreamTest() throws IOException {
    PrintStream out = System.out;
    // 默认情况下,PrintStream输出的位置是标准输出,即显示器
    out.println("hello!");
    out.write("你好哦".getBytes());
    // 可以修改打印流输出的位置
    // 比如修改打印位置为文件中
    System.setOut(new PrintStream("D:\\hacker.txt"));
    System.out.println("华仔华仔!");
    out.close();
}


PrintWriter是字符打印流,代码演示:


/**
 * 字符打印流
 */
@Test
public void PrintWriterTest() throws IOException {
    PrintWriter printWriter = new PrintWriter(System.out);
    printWriter.println("你好");
    // 可以修改打印流输出的位置
    // 比如修改打印位置为文件中
    PrintWriter pw = new PrintWriter(new FileWriter("D:\\hacker.txt"));
    pw.print("我在文件里");
    printWriter.close();
    pw.close();
}


8.配置文件Properties


对于一些不经常改变的配置数据,我们可以采用Properties文件进行保存,如保存数据库的连接信息:

请注意:配置文件的格式(键值对)

键值对之间不能有空格,值不需要使用双引号包裹!💫


ip=192.168.0.1
user=root
password=youarealoser


采用Properties类读文件


/**
 * 读取
 */
@Test
public void read() throws IOException {
    Properties properties = new Properties();
    // 加载配置文件
    properties.load(new FileReader("io\\mysql.properties"));
    // 把 k-v 显示在控制台
    properties.list(System.out);
    // 根据key获取值
    String password = properties.getProperty("password");
    System.out.println(password);
}


采用Properties类修改文件


/**
 * 修改
 */
@Test
public void write() throws IOException {
    Properties properties = new Properties();
    // 设置键值对
    // 如果键已经存在,则等价于修改键
    properties.setProperty("user","汤姆");
    properties.setProperty("passwd","youwillwin");
    // 存储键值对
    properties.store(new FileOutputStream("io\\mysql.properties"),"mysql test data");
}


修改后的配置文件内容:


#mysql test data
#Fri Aug 05 16:53:29 CST 2022
passwd=youwillwin
user=\u6C64\u59C6
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
11月前
|
监控 Java API
现代 Java IO 高性能实践从原理到落地的高效实现路径与实战指南
本文深入解析现代Java高性能IO实践,涵盖异步非阻塞IO、操作系统优化、大文件处理、响应式网络编程与数据库访问,结合Netty、Reactor等技术落地高并发应用,助力构建高效可扩展的IO系统。
320 0
|
8月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
315 1
|
10月前
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
11月前
|
存储 Java Linux
操作系统层面视角下 Java IO 的演进路径及核心技术变革解析
本文从操作系统层面深入解析Java IO的演进历程,涵盖BIO、NIO、多路复用器及Netty等核心技术。分析各阶段IO模型的原理、优缺点及系统调用机制,探讨Java如何通过底层优化提升并发性能与数据处理效率,全面呈现IO技术的变革路径与发展趋势。
230 3
|
10月前
|
SQL Java 数据库连接
Java IO流(一):字节流与字符流基础
本文全面解析Java IO流,涵盖字节流、字符流及其使用场景,帮助开发者理解IO流分类与用途,掌握文件读写、编码转换、异常处理等核心技术,通过实战案例提升IO编程能力。
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
646 23
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
543 0
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
535 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
Java
java 中 IO 流
Java中的IO流是用于处理输入输出操作的机制,主要包括字节流和字符流两大类。字节流以8位字节为单位处理数据,如FileInputStream和FileOutputStream;字符流以16位Unicode字符为单位,如FileReader和FileWriter。这些流提供了读写文件、网络传输等基本功能。
344 10

热门文章

最新文章