Java IO常用操作详解(代码示例)

news2025/1/22 18:08:53

概览

Java I/O操作指的是数据的输入/输出操作。

Java的I/O操作类在java.io包中,主要分以下几种:

  • 基于字节操作的I/O接口: InputStream和OutputStream
  • 基于字符操作的I/O接口: Writer和Reader
  • 基于磁盘操作的I/O接口: File

一、核心类介绍

  • 基于字节的I/O操作,核心是操作字节数组byte[],可以操作任何类型的流数据
  • 基于字符的I/O操作,核心是操作字符数组char[],只能操作字符类型的流数据,如果是非字符的流数据(如图片、视频等)会变成乱码

1、字节输入流

功能说明
ByteArrayInputStream将内存的缓冲区当做InputStream使用将其与FilterInputStream对象相连,将字节流存入文件中
FileInputStream从文件中读取信息将文件对象File转换成输入流,以读取文件中数据
FilterInputStream抽象类,作为装饰器的接口,为其他的InputStream类提供有用的功能
BufferedInputStream提供了缓冲区的操作,提高IO的性能;为传入的输入流添加缓冲功能FilterInputStream子类
DataInputStream与DataOutputStream搭配使用,按照移植方式从流读取基本数据类型;包含用于读取基本数据类型的全部接口FilterInputStream子类

字节输入流

2、字节输出流

功能说明
ByteArrayOutputStream在内存中创建缓冲区。所有送往流的数据都要放置在此缓冲区可以方便的将输入流转换成字节数组
FileOutputStream用于将信息写入文件
FilterOutputStream抽象类,作为装饰器的接口,为其他OutputStream提供有用的功能
BufferedOutputStream提供了缓冲区的操作,提高IO的性能;为传入的输出流添加缓冲功能,可以调用flush()清空缓冲区FilterOutputStream子类
DataOutputStream与DataInputStream搭配使用,可以按照移植方式向流中写入基本数据类型;包含用于写入基本数据类型的全部接口FilterOutputStream子类

字节输出流

3、字符输入流

功能说明
InputStreamReader将字节输入流InputStream转换成字符输入流
FileReader将文件对象File转换成字符输入流InputStreamReader的子类
BufferedReader提供缓冲区功能,提高字符输入流Reader的操作性能
StringReader将字符串转换成字符流操作

字符输入流

4、字符输出流

功能说明
OutputStreamWriter将字节输出流OutputStream转换成字符输出流
FileWriter将文件对象File转换成字符输出流OutputStreamWriter的子类
BufferedWriter提供缓冲区功能,提高字符输出流Writer的操作性能
StringWriter将字符串转换成字符流操作

字符输出流

二、关键操作介绍

1、关闭流

所有数据流在操作完成后,都需要调用close方法关闭,在1.7及之后建议使用try-with-resources语句来使用流,这样可以避免显示的调用close()方法,减少一些重复代码,在操作完成后会自动调用close方法。

try-with-resources语句可以自动close所有实现接口java.io.Closeable的子类对象。

 try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) {
     bos.write(content.getBytes());
     bos.flush();
 }

2、刷新缓存

flush()方法用来强制要求OutputStream对象将暂存于内部缓冲区的数据立即进行实际的写入(一般情况下不需要手动的调用该方法,在内部缓冲区填充满了之后,会自动执行实际的写入操作,在调用close()方法时也会自动调用flush()方法)

3、序列化流和反序列化流

对象的序列化就是将对象转化为byte序列,反之叫做反序列化,ObjectOutputStream是序列化流,ObjectInputStream是反序列化流。

被操作的对象必须实现序列化接口Serializable,如果不想某个字段进行序列化,可以使用transient来修饰字段,使得该字段不进行序列化,也可以通过重写writeObjectOverride()readObjectOverride()方法来进行手动序列化。

静态变量也不能进行序列化,因为所有的对象都共享同一份静态变量值

1)ObjectOutputStream序列化流

主要的方法是writeObject,存储对象的类、类的签名以及这个类及其父类中所有非静态和非瞬时的字段的值

public final void writeObject(Object obj) throws IOException {
    if (enableOverride) {
        writeObjectOverride(obj);
        return;
    }
    try {
        writeObject0(obj, false);
    } catch (IOException ex) {
        if (depth == 0) {
            writeFatalException(ex);
        }
        throw ex;
    }
}

2)ObjectInputStream反序列化流

主要的方法是readObject,读回对象的类、类的签名以及这个类及其父类中所有非静态和非瞬时的字段的值

    public final Object readObject()
        throws IOException, ClassNotFoundException
    {
        if (enableOverride) {
            return readObjectOverride();
        }

        // if nested read, passHandle contains handle of enclosing object
        int outerHandle = passHandle;
        try {
            Object obj = readObject0(false);
            handles.markDependency(outerHandle, passHandle);
            ClassNotFoundException ex = handles.lookupException(passHandle);
            if (ex != null) {
                throw ex;
            }
            if (depth == 0) {
                vlist.doCallbacks();
            }
            return obj;
        } finally {
            passHandle = outerHandle;
            if (closed && depth == 0) {
                clear();
            }
        }
    }

三、代码示例

import org.springframework.util.StopWatch;
import java.io.*;
public class FileUtilTest {
    /**
     * 复制文件
     */
    public static void copyFile(String fromFileName, String toFileName) throws Exception {
        File fromFile = new File(fromFileName);
        File toFile = new File(toFileName);
        StopWatch watch = new StopWatch("fileTest");
        watch.start("copy");

        if (!fromFile.exists()) {
            System.out.println("源文件不存在");
            System.exit(1);
        }
        if (!toFile.getParentFile().exists()) {
            toFile.getParentFile().mkdirs();
        }

        try (InputStream is = new FileInputStream(fromFile);
             OutputStream os = new FileOutputStream(toFile)) {
            int temp = 0;
            byte[] data = new byte[4096];

            while ((temp = is.read(data)) != -1) {
                os.write(data, 0, temp);
            }
            watch.stop();
            System.out.println(watch.prettyPrint());
        }
    }

    /**
     * 通过字符流将字符串写入到文件中
     */
    public static void write(String fileName, String content) throws IOException {

        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try (Writer out = new FileWriter(file)) {
            out.write(content);
            out.flush();
        }
    }

    /**
     * 通过字节流将字符串写入到文件中,增加缓冲区功能
     */
    public static void writeBuffer(String fileName, String content) throws IOException {
        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) {
            bos.write(content.getBytes());
            bos.flush();
        }
    }

    /**
     * 通过字符流将字符串写入到文件中,增加缓冲区功能
     */
    public static void writeBufferedWriter(String fileName, String content) {
        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
            bw.write(content);
            bw.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过字符流,从文件中读取字符串内容
     */
    public static void readChar(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            return;
        }
        try (Reader in = new FileReader(file)) {
            char[] data = new char[4096];
            int len;
            StringBuilder sb = new StringBuilder();
            while ((len = in.read(data)) != -1) {
                sb.append(new String(data, 0, len));
            }
            in.close();
            System.out.println(sb);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 通过字节流,从文件中读取字符串内容
     */
    public static void readByte(String fileName) throws IOException {
        File file = new File(fileName);
        if (!file.exists()) {
            return;
        }
        try (InputStream in = new FileInputStream(file)) {
            byte[] data = new byte[4096];
            int len;
            StringBuilder sb = new StringBuilder();
            while ((len = in.read(data)) != -1) {
                sb.append(new String(data, 0, len));
            }
            System.out.println(sb);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过字符流,从文件中读取字符串内容,增加缓冲区功能
     */
    public static void readBufferReader(String fileName) throws Exception {
        File file = new File(fileName);
        if (!file.exists()) {
            return;
        }
        try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
        }

    }

    /**
     * 通过字节流,从文件中读取字符串内容,增加缓冲区功能
     */
    public static void readBuffer(String fileName) throws Exception {
        File file = new File(fileName);
        if (!file.exists()) {
            return;
        }
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
            int len;
            byte[] data = new byte[4096];
            while ((len = bis.read(data)) != -1) {
                System.out.println(new String(data, 0, len));
            }
        }
    }

    /**
     * 将文件内容转换成字节数组
     */
    public static byte[] file2OutStream(String fileName) throws Exception {
        File file = new File(fileName);
        if (!file.exists()) {
            return null;
        }
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
             ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            int len;
            byte[] data = new byte[4096];
            while ((len = bis.read(data)) != -1) {
                bos.write(data, 0, len);
            }
            return bos.toByteArray();
        }
    }

    /**
     * 将Java对象序列化存储在到文件中
     */
    public static void objWrite(String fileName) {
        File file = new File(fileName);
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
            oos.writeObject("Hello ,World");
            oos.writeBoolean(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 从序列化文件中反序列化出Java对象
     */
    public static void objRead(String fileName) {
        File file = new File(fileName);
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            Object o = ois.readObject();
            System.out.println(o.getClass());
            System.out.println("o = " + o);
            System.out.println("ois.readBoolean() = " + ois.readBoolean());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

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

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

相关文章

5个令人惊艳的AI项目,开源了。。

大家好,我是 Jack。 今天清明,小伙伴们都去哪里玩了? 上个月我已经出去浪过了,清明就老实在家歇着了。 翻看了一些最近热点的开源项目,发现还是 AIGC 的天下。 今天,我将继续着重挑选几个近期的优质开源…

2023第十四届蓝桥杯C++B组菜鸡的落幕

时隔几天,终于还是忍不住来复盘一下蓝桥杯了,还记得去年参加做下填空,再做对个把编程,后面不会的大题打打表混混分,最后就能混个省奖, 这回估计凉透了,填空没对似乎,编程也没对几个,…

Kettle8.2.0连接Hive3.1.2(踩坑,亲测有效)

这是目前遇到的最简单但最头疼的安装,因为是在公司之前用过的服务器上进行安装测试,加上又使用比较新的版本,结果踩了不少坑。Kettle连接Hive这个坑,从2023年4月11日下午开始,一致到2023年4月12日中午才弄好&#xff0…

uni-app常用配置

保存自动格式化 工具》设置》编辑器设置》保存时自动格式化 JS语法检查 安装eslint-js插件eslint-js - DCloud 插件市场 用于校验js和html中的js代码https://ext.dcloud.net.cn/plugin?id2037工具》设置》插件配置》eslint-js 启用实时校检 Vue语法检查 安装eslint-vue插…

【星界探索——通信卫星】铱星:从“星光坠落”到“涅槃重生”,万字长文分析铱星卫星系统市场

【星界探索——通信卫星】铱星:从“星光坠落”到“涅槃重生”一、铱星简介二、铱星系统设计思路2.1 工作原理2.2 铱星布局三、铱星优势四、发展历程五、第一代铱星公司的破产原因分析5.1 终端和资费价格高昂,市场用户群体小5.2 财务危机5.3 市场分析不足…

一文吃透低代码平台源代码交付的重要性(避坑指南)

一、前言 作为这两年IT界的风口,低代码在众人眼里已经不是什么陌生的概念。 对标于传统的纯代码开发,低代码是一种快速开发软件(应用程序)的方法,平台通过对大量功能与场景做提前封装,使得用户可以在可视…

MySQL开发05-MySQL开发规范

文章目录1、命名规范2、表设计规范3、索引规范4、SQL语句规范5、SQL脚本规范6、数据架构规范7、配置文件建议8、其他规范9、总结1、命名规范 命名应有意义,包括库名、表名、用户名等,以使用方便记忆、描述性强的可读性名称为第一准则,尽量避…

Docker网络案例

bridge 是什么 Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机…

C#基础复习

语句 目录 语句 switch: 跳转语句 标签语句 标签: 标签语句的作用域 goto语句 using 语句 资源的包装使用 using 语句示例: 多个资源和嵌套 语句是描述某个类型或让程序执行某个动作的源代码指令 块在语法上算作一个单条嵌入语句。任何语…

【cmake学习】搭建一个简单的cmake工程(初级版)

目录 1、工程框架介绍 2、编写CMakeLists.txt (1) 限制cmake最低版本、工程命名 (2) 引入头文件目录 (3) 引入库目录(可选) (4) 引入源文件 (5) 生成可执行文件 / 生成动静态库 (6) 链接库文件(可选) 3、完整CMakeLists…

uefi 内存管理

PEI 阶段 PEI 阶段最为重要的结构是HOB, 初始化内存服务前,PEI 申请的内存其实是插入到FV 文件 也就是FLASH 里面去运行。 在此状态下,FLASH 可读不可写,所以是不能使用全局变量的。如果有需要模块间共享信息,需要申请HOB. HO…

gtkmm给组件添加css

设置方式 使用CSS分为两步,1:为组件设这css名称,2:加载样式表。 样式表我们写在文件中就行(似乎也可以从字符串加载,不过不推荐)。 1. 设置css名称 使用gtk的接口:gtk_widget_class_set_css_name()。 这…

rk3568点亮E-ink

rk3568 Android11/12 适配 E-ink “EINK”是英语ElectronicInk的缩写。翻译成中文为“电子墨水”。电子墨水由数百万个微胶囊(Microcapsules)所构成,微胶囊的大小约等同于人类头发的直径。每个微胶囊里含有电泳粒子──带负电荷的白色以及带正电荷的黑色粒子&#…

Ubuntu 交叉编译Windows 版本的ffmpeg最佳实践

之前介绍在Windows上采用msys2+minGW或者cygwin在Windows编译方法。很多读者觉得在Windows搭建一个类Linux比较麻烦或者说方法不够通用,本文就介绍在流行的Linux发行版Ubuntu上编译window版本的ffmpeg。即介绍一种通用办法来编译Windows版本ffmpeg,该方法可以推广到android,…

算法 贪心4 || 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

860.柠檬水找零 很简单的一题&#xff0c;完全是常识题 class Solution { public:bool lemonadeChange(vector<int>& bills) {unordered_map<int,int> map;for(int i 0; i < bills.size(); i){map[bills[i]];if(bills[i] ! 5){if(map[5] 0) return fals…

【Linux】程序中获取和设置cpu和mem相关信息

这里是目录一、CPU和MEM信息1.1、CPU信息1.1.1、CPU核心数1.1.2、CPU频率读取和调整1.1.3、CPU温度1.2、MEM信息二、C程序读取CPU和MEM信息三、测试写在前面&#xff1a; 记录一下日常&#xff0c;之前有做过相关工作&#xff0c;但是没有记录下来&#xff0c;因此写一写文章。…

使用hbuilder连接夜神模拟器调试app

1. Hbuilder设置 这里端口号随便用一个没有被占用的&#xff1b; 路径夜神模拟器的安装路径下的nox_adb.exe的路径。 2. 夜神模拟器设置 设置如下&#xff1a; 工具&#xff0c;设置&#xff0c;关于平板电脑&#xff08;这里应该没有开发者模式选项&#xff0c;这是我配好之…

【LeetCode】剑指 Offer 53. 在排序数组中查找数字 p263 -- Java Version

1. 题目介绍&#xff08;53. 在排序数组中查找数字&#xff09; 面试题53&#xff1a;在排序数组中查找数字 一共分为三小题&#xff1a; 题目一&#xff1a;数字在排序数组中出现的次数题目二&#xff1a;0 ~ n-1 中缺失的数字题目三&#xff1a;数组中数值和下标相等的元素 2…

【创作赢红包】面向对象基础概念

什么是面向对象 面向对象&#xff08;Object Oriented&#xff09;是软件开发方法&#xff0c;一种编程范式&#xff0c;它是一种对现实世界理解和抽象的方法&#xff0c;是计算机编程技术发展到一定阶段后的产物。 早期的计算机编程是基于面向过程的方法&#xff0c;如实现算…

前端工程化:环境准备—NodeJs安装-Vue项目开发流程

一、前端工程化-Yapi 介绍&#xff1a;YApi 是高效、易用、功能强大的 api 管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务 地址&#xff1a; http://yapi.smart-xwork.cn/ 具体操作步骤&#xff1a; 1、添加项目 2、添加接口&#xff1a;根据ID查…