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

news/2024/11/15 4:01:08/

概览

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 objectint 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.ppmy.cn/news/39798.html

相关文章

【多线程与高并发(锁)】1、锁的概念、分类和状态

1、锁的概念 java当中的锁、是在多线程环境下为保证共享资源健康、线程安全的一种手段。 线程操作某个共享资源之前,先对资源加一层锁,保证操作期间没有其他线程访问资源,当操作完成后,再释放锁。 2、锁的分类 Java中的锁按照…

I2C协议

目录 I2C协议 E2PROM AT24C02 I2C协议 假设主设备想要向从设备发送数据: 1. 主发送器发送START条件并寻址从接收器 2. 主发送器将数据发送到从接收器 3. 主发送器以STOP条件终止传输 如果主设备想要从从设备接收/读取数据: 1. 主发送器发送START条件并…

vue elementUI select下拉框设置默认值(赋值)失败

vue elementUI select下拉框设置默认值 要为select下拉框设定默认值&#xff0c;只需要把 v-model 绑定的值和你想要选中 option 的 value 值设置一样即可。 下面上代码&#xff1a; html部分代码&#xff1a; <el-select v-model"valuetype" change"ch…

前端中 try-catch 捕获不到哪些异常和常见错误

在开发过程中&#xff0c;我们的目标是 0error&#xff0c;0warning。 但有很多因素并不是我们可控的&#xff0c;为了避免某块代码的错误&#xff0c;影响到其他模块或者整体代码的运行&#xff0c;我们经常会使用try-catch模块来主动捕获一些异常或者错误。 比如我们在获取…

SpringBoot 使用Prometheus采集自定义指标数据

一、我们需要什么指标 对于DDD、TDD等&#xff0c;大家比较熟悉了&#xff0c;但是对于MDD可能就比较陌生了。MDD是Metrics-Driven Development的缩写&#xff0c;主张开发过程由指标驱动&#xff0c;通过实用指标来驱动快速、精确和细粒度的软件迭代。MDD可使所有可以测量的东…

ChatGPT 与未来软件开发的关系

在过去几年中&#xff0c;自然语言处理 (NLP) 取得了重大进展&#xff0c;并为软件开发开辟了新的可能性。最令人印象深刻的 NLP 应用之一是聊天机器人的开发&#xff0c;它能够通过自然语言与用户交流。ChatGPT 就是这样一种聊天机器人&#xff0c;这是一种由 OpenAI 开发的大…

《扬帆优配》国际原油市场巨震 海外金融稳定性再遭考验

当地时间4月2日&#xff0c;以沙特为代表的“欧佩克”&#xff08;下称OPEC&#xff09;突然宣告&#xff0c;在上一年10月减产200万桶/日的基础上&#xff0c;进一步自愿减产原油超160万桶/日。至此&#xff0c;OPEC计划减产规模将达全球石油产值的约3.5%。 投资者更关怀的是&…

TCP 的可靠传输

目录可靠传输有啥用确认应答超时重传总结可靠传输有啥用 我们知道相比于 UDP, TCP 的传输是可靠的, 啥意思呢? 就是 UDP 发送的数据, 它自己不知道发送的数据对方是否接收到. 而 TCP 发送的数据, 它知道对方是否接收到, 也就是说对方会给个应答. 假设一个场景 : 甲要付款给乙…