Java IO流

IO 即 Input / Output ,输入输出流。IO流在Java中分为输入流和输出流,而根据数据的处理方式又分为字节流和字符流。

Java IO 流的 40 多个类都是从如下 4 个 抽象类基类中派生出来的。

  • InputStream /Reader : 所有的输入流的基类,前者是字节输入流,后者是字符输入流
  • OutputStream / Writer : 所有的输出流的基类,前者是字节输出流,后者是字符输出流

字节流

InputStream(字节输入流)

InputStream 用于从源头(通常是文件)读取数据(字节信息)到内存中,java.io.InputStream 抽象类是所有字节输入流的父类。

InputStream 常用方法:

  • read() :返回输入流中下一个字节的数据。返回的值介于 0 - 255 之间。如果未读取任何字节,代码返回 -1 ,表示文件结束。
  • read(byte b[ ] ):从输入流读取一些字节存储到数组 b 中。如果数组 b 的长度为 0 ,则不读取。如果没有可用字节读取,返回 -1。如果有可用字节读取,则最多读取的字节数等于 b.length ,返回读取的字节数。这个方法等价于 read(b , 0 , b.length)。
  • read(byte b[] , int off , int len):在 read(byte b [ ]) 方法的基础上增加了 off 参数(偏移量)和 len参数(要读取的最大字节数)。
  • skip(long n):忽略输入流中的 n 个字节,返回实际忽略的字节数
  • avaliable():返回输入流中可以读取的字节数
  • close():关闭输入流释放·相关的系统资源
    public static void main(String[] args) {try(InputStream fis = new FileInputStream("IO/input.txt")){System.out.println("number of remaining bytes: " + fis.available());int content;long skip = fis.skip(2);System.out.println("the actual number of bytes skipped: " +skip);System.out.println("the content read from file: ");while((content = fis.read()) != -1){System.out.println((char) content);}}catch (IOException e){e.printStackTrace();}}

input文件内容:

输出:

不过,一般不会单独使用 FileInputStream ,通常配合 BufferedInputStream (字符缓冲输入流)使用

  public static void main(String[] args){//新建一个 BufferedInputStream 对象try(BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("IO/input.txt"))){// 读取文件内容byte[] content = new byte[bufferedInputStream.available()];bufferedInputStream.read(content , 0 , bufferedInputStream.available());String result = new String(content);System.out.println(result);}catch (IOException E){E.printStackTrace();}}

输出:

DataInputStream 用于读取指定类型数据,不能单独使用,必须结合其它流,比如 FileInputStream。

FileInputStream fileInputStream = new FileInputStream("input.txt");
//必须将fileInputStream作为构造参数才能使用
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
//可以读取任意具体的类型数据
dataInputStream.readBoolean();
dataInputStream.readInt();
dataInputStream.readUTF();

 ObjectInputStream 用于从输入流中读取 Java 对象(反序列化),ObjectOutputStream 用于将对象写入到输出流(序列化)。

ObjectInputStream input = new ObjectInputStream(new FileInputStream("object.data"));
MyClass object = (MyClass) input.readObject();
input.close();

OutputStream (字节输入流)

OutputStream 用于将数据(字节信息)写入到目的地(通常是文件),java.io.OutputStream 抽象类是所有字节输出流的父类。

OutputStream 常用方法:

  • write() :将特定字节写入到输出流。
  • write(byte b[ ] ):将数组 b 写入到输出流。这个方法等价于 write(b , 0 , b.length)。
  • write(byte b[] , int off , int len):在 write(byte b [ ]) 方法的基础上增加了 off 参数(偏移量)和 len参数(要写入的最大字节数)。
  • flush():刷新次输出流并强制写出所有缓冲的输出字节
  • close():关闭输出流释放·相关的系统资源

FileOutputStream 是最常用的字节输出流对象,可直接指定文件路径,可以直接输出单字节数据,也可以输出指定的字节数组。

    public static void main(String[] args) {try(FileOutputStream outputStream = new FileOutputStream("IO/output.txt")){byte[] array = "hello,world".getBytes();outputStream.write(array); //将 array 写入到 output 文件,会覆盖 output 文件内容}catch (IOException e){e.printStackTrace();}}

结果:

类似于 FileInputStream ,FileOutputStream 通常也会配合 BufferedOutputStream(字节缓冲输出流)来使用。

    public static void main(String[] args) {try(BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("IO/output.txt"))){byte[] out = "hello,world".getBytes();bufferedOutputStream.write(out);}catch (IOException e){e.printStackTrace();}}

DataOutputStream 用于写入指定类型数据,不能单独使用,必须结合其它流,比如 FileOutputStream

// 输出流
FileOutputStream fileOutputStream = new FileOutputStream("out.txt");
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
// 输出任意数据类型
dataOutputStream.writeBoolean(true);
dataOutputStream.writeByte(1);

ObjectOutputStream 用于从输入流中读取 Java 对象(ObjectOutputStream ,反序列化),ObjectOutputStream 将对象写入到输出流(ObjectOutputStream ,序列化)

ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("file.txt")
Person person = new Person("tom", 16);
output.writeObject(person);

字符流

虽然文件读写或者网络发送接收的信息最小存储单元是字节,但是字符流是由Java 虚拟机将字节转换得到的,这个过程比较耗时,如果不知道编码类型还很容易出现乱码

将上面的 FileInputStream 代码示例中的 input.txt 文件内容改成中文:

输出:

因此,IO流提供了一个直接操作字符的接口,方便平时对字符的流操作。比如音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。


Reader(字符输入流)

Reader 用于从源头(通常是文件)读取数据(字符信息)到内存中,java.io.Reader 抽象类是所有字符输入流的父类。

Reader 用于读取文本,InputStream 用于读原始字节。

Reader 常用方法:

  • read() :从输入流读取一个字符
  • read(char[ ] cbuf):从输入流读取一些字符存储到数组 cbuf 中。这个方法等价于 read(cbuf, 0 , cbuf.length)。
  • read(char[] cbuf , int off , int len):在 read(char[] cbuf) 方法的基础上增加了 off 参数(偏移量)和 len参数(要读取的最大字节数)。
  • skip(long n):忽略输入流中的 n 个字符,返回实际忽略的字节数
  • close():关闭输入流释放相关的系统资源
// 字节流转换为字符流的桥梁
public class InputStreamReader extends Reader {
}
// 用于读取字符文件
public class FileReader extends InputStreamReader {
}

FileReader 是继承于 InputStreamReader的

    public static void main(String[] args) {try (FileReader fileReader = new FileReader("IO/input.txt");) {int content;long skip = fileReader.skip(3);System.out.println("The actual number of bytes skipped:" + skip);System.out.print("The content read from file:");while ((content = fileReader.read()) != -1) {System.out.print((char) content);}} catch (IOException e) {e.printStackTrace();}}

input文件:

输出:


Writer(字符输出流)

Writer用于将数据(字符信息)写入到目的地(通常是文件),java.io.Writer 抽象类是所有字符输出流的父类

Writer常用方法:

  • write(int c ) :写入单个字符
  • write(char[] b ):将数组 b 写入到输出流。这个方法等价于 write(b , 0 , b.length)。
  • write(char[] b , int off , int len):在 write(char[] b) 方法的基础上增加了 off 参数(偏移量)和 len参数(要写入的最大字符数)。
  • write(String s):将字符串 s 写入到输出流。这个方法等价于 write(s , 0 , s.length())。
  • write(String s, int off , int len):在 write(String s) 方法的基础上增加了 off 参数(偏移量)和 len参数(要写入的最大字符数)。
  • append(char c ):将指定的字符附加到指定的 Writer 对象并返回该 Writer 对象。
  • flush():刷新次输出流并强制写出所有缓冲的输出字符
  • close():关闭输出流释放·相关的系统资源
// 字符流转换为字节流的桥梁
public class OutputStreamWriter extends Writer {
}
// 用于写入字符到文件
public class FileWriter extends OutputStreamWriter {
}

FileWriter 继承于 OutputStreamWriter.

    public static void main(String[] args) {try (Writer output = new FileWriter("IO/output.txt")) {output.write("你好,世界");} catch (IOException e) {e.printStackTrace();}}

输出结果:


字节缓冲流

IO 操作是很消耗性能的,缓冲流将数据加载至缓冲区,一次性读取/写入多个字节,从而避免频繁的 IO 操作,提高流的传输效率。


BufferedInputStream (字节缓冲输入流)

BufferedInputStream 从源头(通常是文件)读取数据(字节信息)到内存的过程中不会一个字节一个字节的读取,而是会先将读取到的字节存放在缓存区,并从内部缓冲区中单独读取字节。这样大幅减少了 IO 次数,提高了读取效率。

// 新建一个 BufferedInputStream 对象
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("input.txt"));

 BufferedInputStream 内部维护了一个缓冲区,这个缓冲区实际就是一个字节数组。


BufferedOutputStream (字节缓冲输出流)

BufferedOutputStream 将数据(字节信息)写入到目的地(通常是文件)的过程中不会一个字节一个字节的写入,而是会先将要写入的字节存放在缓存区,并从内部缓冲区中单独写入字节。这样大幅减少了 IO 次数,提高了读取效率

try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {byte[] array = "JavaGuide".getBytes();bos.write(array);
} catch (IOException e) {e.printStackTrace();
}

类似于 BufferedInputStream ,BufferedOutputStream 内部也维护了一个缓冲区,并且,这个缓存区的大小也是 8192 字节。


字符缓冲流

BufferedReader (字符缓冲输入流)和 BufferedWriter(字符缓冲输出流)类似于 BufferedInputStream(字节缓冲输入流)和BufferedOutputStream(字节缓冲输入流),内部都维护了一个字节数组作为缓冲区。不过,前者主要是用来操作字符信息。


打印流

System.out.println("hello,world")

System.out 实际是用于获取一个 PrintStream 对象,print 方法实际调用的是 PrintStream 对象的 write 方法。

PrintStream 属于字节打印流,与之对应的是 PrintWriter(字符打印流)。PrintStreamOutputStream 的子类,PrintWriterWriter 的子类。

public class PrintStream extends FilterOutputStreamimplements Appendable, Closeable {
}
public class PrintWriter extends Writer {
}

随机访问流

随机访问流,指的是支持随意跳转到文件的任意位置进行读写的 RandomAccessFile

RandomAccessFile 的构造方法如下,我们可以指定 mode (读写模式)。

// openAndDelete 参数默认为 false 表示打开文件并且这个文件不会被删除
public RandomAccessFile(File file, String mode)throws FileNotFoundException {this(file, mode, false);
}
// 私有方法
private RandomAccessFile(File file, String mode, boolean openAndDelete)  throws FileNotFoundException{// 省略大部分代码
}

读写模式主要有以下四种:

  • r:只读模式
  • rw:读写模式
  • rws:相对于 rw,rws 同步更新对“文件的内容”或“元数据”的修改到外部存储设备
  • rwd:相对于 rw,rwd 同步更新对“文件的内容”的修改到外部存储设备

文件内容指的是文件中实际保存的数据,元数据则是用来描述文件属性:比如文件的大小信息、创建和修改时间。

output文件:

执行:

 public static void main(String[] args) {try(RandomAccessFile accessFile = new RandomAccessFile(new File("IO/output.txt"),"rw")){System.out.println("当前文件的读写偏移量:" + accessFile.getFilePointer());accessFile.seek(accessFile.length());System.out.println("seek设置后的文件读写偏移量:" + accessFile.getFilePointer());accessFile.write(new byte[]{'H','E','L','L','O'});}catch (IOException e){e.printStackTrace();}}

结果:

RandomAccessFilewrite 方法在写入对象时,如果对应的位置已经有数据的话,会将其覆盖掉,如果没有的话则写入数据。

RandomAccessFile 比较常见的一个应用就是实现大文件的断点续传。简单来说就是上传文件中途暂停或失败(比如遇到网络问题)之后,不需要重新上传,只需要上传那些未成功上传的文件分片即可。

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

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

相关文章

论文阅读之《Learn to see in the dark》

Learning to See in the Dark-CVPR2018 Chen ChenUIUC(伊利诺伊大学厄巴纳-香槟分校) Qifeng Chen, Jia Xu, Vladlen Koltun Intel Labs(英特尔研究院) 文章链接:https://arxiv.org/pdf/1805.01934.pdfhttps://arxiv.org/pdf/1805.01934.p…

Android Studio展示Activty生命周期

前言 本文章以及之后文章的程序版本使用Android Studio 2022.3.1 Patch 1 版本编辑,使用语言为java,最低支持API 27 Android 8.1,构建工具版本如下: 本文章主要是介绍Activty跳转和删除,以备后续使用,所以就…

计算机的字符与编码集

文章目录 前言一、字符编码集的历史1.ASCII码2.Extended ASCII码3.字符编码集的国际化 二、中文编码集 前言 今天给大家介绍计算机的字符与编码集,分为两部分:字符编码集的历史、中文编码集。 一、字符编码集的历史 这部分包含三个板块内容&#xff1a…

【通信系列 5 -- HTTPS 介绍】

文章目录 1.1 HTTPS链接网址1.1.1 HTTPS 产生背景1.1.2 HTTPS工作内容1.1.3 SSL/TLS1.1.4 TLS 的命名规范1.1.5 TLS 加密算法1.1.6 分组模式1.1.7 摘要算法1.1.8 非对称加密1.1.9 CA认证 1.2 openssl1.2.1 RSA 签名验签 1.1 HTTPS链接网址 HTTP 是一种 超文本传输协议(Hyperte…

DOCKER本地仓库

概述 随着docker的应用越来越多,安装部署越来越方便,批量自动化的镜像生成和发布都需要docker仓库的本地化应用。 试用了docker的本地仓库功能,简单易上手,记录下来以备后用。 环境 centos:CentOS release 7.0 (F…

CANoe创建仿真工程

CANoe创建仿真工程 写在前面仿真工程的创建创建工程添加CAN数据库添加系统变量创建面板创建网络节点为节点添加代码工程运行测试总结 写在前面 Canoe的安装不是特别方便,我是参加了松勤的培训课程,不仅需要安装软件还需要安装驱动,刚刚学习的…

【PWN · 栈迁移】[CISCN 2019东南]PWN2

一道非常典型、适合用作学习栈迁移的题目。 前言 当存在栈溢出但是溢出字符数并不多的情况下,可以尝试在别处构造rop链,通过栈迁移到目标内存区域,执行rop链。这里不讲栈迁移原理,仅是对题目的分析,适合对栈迁移有初步…

WPF中的多重绑定

MultiBinding 将会给后端传回一个数组, 其顺序为绑定的顺序. 例如: <DataGridMargin"10"AutoGenerateColumns"False"ItemsSource"{Binding Stu}"><DataGrid.Columns><DataGridTextColumn Binding"{Binding Id}" Header…

bash一行输入,多行回显demo脚本

效果图&#xff1a; 脚本&#xff1a; #!/bin/bash # 定义一个变量&#xff0c;用来存储输入的内容 input"" # 定义一个变量&#xff0c;用来存储输入的字符 char""# 为了让read能读到空格键 IFS_store$IFS IFS# 提示内容&#xff0c;在while循环中也有&a…

three.js入门 —— 实现第一个3D案例

前言&#xff1a; three.js入门&#xff0c;根据文档实现第一个3D案例 效果图&#xff1a; 代码实现&#xff1a; const scene new THREE.Scene();//创建一个长方体几何对象Geometryconst geometry new THREE.BoxGeometry(100, 100, 100);//创建一个网络基础材质的材质对象…

机器人革命:脑洞大开的前沿机器人技术!

原创 | 文 BFT机器人 01 由生物启发的多模式移动形态机器人 在一个不断运动的世界中&#xff0c;一种新开发的名为M4&#xff08;多模式移动形态机器人&#xff09;的机器人展示了在包括滚动、飞行和行走在内的八种不同运动模式之间切换的能力。这款机器人由加州理工学院自主…

SOLIDWORKS® 2024 新功能 - 3D CAD

1、 先前版本的兼容性 • 利用您订阅的 SOLIDWORKS&#xff0c;可将您的 SOLIDWORKS 设计作品保存为旧版本&#xff0c;与使用旧版本 SOLIDWORKS 的供应商无缝协作。 • 可将零件、装配体和工程图保存为新版本前两年之内的SOLIDWORKS 版本。 优点&#xff1a; 即使其他用户正…

conda 创建虚拟环境

1.为什么要创建虚拟环境 我们在做开发或者跑论文实验可能会同时进行多个任务&#xff0c;这些任务可能会依赖于不同的python环境&#xff0c;比如有的用到3.6有的用到3.7&#xff0c;这时我们创建不同版本的python&#xff0c;放到虚拟环境中给不同的任务分别提供其所需要的版本…

Git相关知识(1)

目录 1.初识Git 1.基础知识 2.centos中下载 2.基本操作 1.创建本地仓库 2.配置本地仓库 3.版本库、工作区、暂存区 4.添加文件 5.add和commit对git文件的作用 6.修改文件 7.版本回退 8.撤销修改 9.删除文件 3.分支操作 1.HEAD与分支 2.创建分支 3.删除分支 …

基于SSM的班级事务管理系统

基于SSM的班级事务管理系统 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台界面 登录界面 班委界面 学生界面 管理员界面 摘要 基于SSM&#xff08;Spring、Spring…

ARM-day9作业

main.c: #include "uart.h"#include "key_it.h"int main(){char c;char *s;uart4_init(); //串口初始化//中断初始化key_it_config();key3_it_config();//完成GPIO相关初始化all_led_init();//风扇初始化fs_init();//蜂鸣器初始化fmq_init();while(1){…

矿区井下智慧用电安全监测解决方案

一、背景 矿区井下作业具有复杂的环境和较高的危险性&#xff0c;对于用电安全的要求尤为严格。传统的管理模式和监测方法往往无法实时、准确地掌握井下用电情况&#xff0c;对安全隐患的排查与预防存在一定局限性。因此&#xff0c;引入智慧用电安全监测解决方案&#xff…

黑马JVM总结(三十二)

&#xff08;1&#xff09;类加载器-线程上下文1 使用的应用程序类加载器来完成类的加载&#xff0c;不是用的启动类加载器&#xff0c;jdk在某些情况下要打破&#xff0c;双亲委派的模式&#xff0c;有时候需要调用应用程序类加载器来完成类的加载&#xff0c;否则有些类它是找…

YB4058是一款经济高效、完全集成的高输入电压单电池锂离子电池充电器

高输入电压充电器支持I2C和OVP保护 概述&#xff1a; YB4058是一款经济高效、完全集成的高输入电压单电池锂离子电池充电器。充电器使用了锂离子电池所需的CC/CV充电曲线。充电器可接受高达27V的输入电压&#xff0c;但当输入电压超过OVP时禁用阈值&#xff0c;通常为6.8V&am…

倒置边框半径卡片

效果展示 CSS 知识点 实现多曲面的思路 实现整体布局 <div class"card"><div class"img_box"></div><div class"content"><div class"price"></div></div> </div>.card {position…