javaIO流之字节流

news2024/12/22 13:40:31

目录

  • 1、字节输出流(OutputStream)
  • 2、FileOutputStream类
    • 2.1FileOutputStrea 的构造方法
    • 2.2FileOutputStream 写入字节数据
    • 2.3FileOutputStream实现数据追加、换行
  • 3、字节流入流(InputStream)
  • 4、FileInputStream类
    • 4.1FileInputStream的构造方法
    • 4.2FileInputStream读取字节数据
    • 4.3字节流FileInputstream复制图片
  • 5、小结

我们必须得明确一点,一切文件(文本、视频、图片)的数据都是以二进制的形式存储的,传输时也是。所以,字节流可以传输任意类型的文件数据。

1、字节输出流(OutputStream)

java.io.OutputStream 是字节输出流的超类(父类),我们来看一下它定义的一些共性方法:

  • close() :关闭此输出流并释放与此流相关联的系统资源。

  • flush() :刷新此输出流并强制缓冲区的字节被写入到目的地。

  • write(byte[] b):将 b.length 个字节从指定的字节数组写入此输出流。

  • write(byte[] b, int off, int len) :从指定的字节数组写入 len 字节到此输出流,从偏移量 off开始。 也就是说从off个字节数开始一直到len个字节结束

2、FileOutputStream类

OutputStream 有很多子类,我们从最简单的一个子类 FileOutputStream 开始。看名字就知道是文件输出流,用于将数据写入到文件。

2.1FileOutputStrea 的构造方法

  • 使用文件名创建 FileOutputStream 对象。
String fileName = "example.txt";
FileOutputStream fos = new FileOutputStream(fileName);

以上代码使用文件名 “example.txt” 创建一个 FileOutputStream 对象,将数据写入到该文件中。如果文件不存在,则创建一个新文件;如果文件已经存在,则覆盖原有文件。

  • 使用文件对象创建 FileOutputStream 对象。
File file = new File("example.txt");
FileOutputStream fos = new FileOutputStream(file);

FileOutputStream 的使用示例:

FileOutputStream 的使用示例:
FileOutputStream fos = null;
try {
  fos = new FileOutputStream("example.txt");
  fos.write("张三".getBytes());
} catch (IOException e) {
  e.printStackTrace();
} finally {
  if (fos != null) {
    try {
      fos.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

以上代码创建了一个 FileOutputStream 对象,将字符串 “沉默王二” 写入到 example.txt 文件中,并在最后关闭了输出流。

2.2FileOutputStream 写入字节数据

使用 FileOutputStream 写入字节数据主要通过 write 方法:

write(int b)
write(byte[] b)
write(byte[] b,int off,int len)  //从`off`索引开始,`len`个字节

①、写入字节:write(int b) 方法,每次可以写入一个字节,代码如下:

// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");     
// 写出数据
fos.write(97); // 第1个字节
fos.write(98); // 第2个字节
fos.write(99); // 第3个字节
// 关闭资源
fos.close();

字符 a 的 ASCII 值为 97,字符 b 的ASCII 值为 98,字符 b 的ASCII 值为 99。也就是说,以上代码可以写成:

// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");     
// 写出数据
fos.write('a'); // 第1个字节
fos.write('b'); // 第2个字节
fos.write('c'); // 第3个字节
// 关闭资源
fos.close();

当使用 write(int b) 方法写出一个字节时,参数 b 表示要写出的字节的整数值。由于一个字节只有8位,因此参数 b 的取值范围应该在 0 到 255 之间,超出这个范围的值将会被截断。例如,如果参数 b 的值为 -1,那么它会被截断为 255,如果参数 b 的值为 256,那么它会被截断为 0。

在将参数 b 写入输出流中时,write(int b) 方法只会将参数 b 的低8位写入,而忽略高24位。这是因为在 Java 中,整型类型(包括 byte、short、int、long)在内存中以二进制补码形式表示。当将一个整型值传递给 write(int b) 方法时,方法会将该值转换为 byte 类型,只保留二进制补码的低8位,而忽略高24位。

例如,如果要写出的整数为 0x12345678,它的二进制补码表示为 0001 0010 0011 0100 0101 0110 0111 1000。当使用 write(int b) 方法写出该整数时,只会将二进制补码的低8位 0111 1000 写出,而忽略高24位 0001 0010 0011 0100 0101 0110。这就是参数 b 的高24位被忽略的原因。

0111 1000 是一个8位的二进制数,它对应的十进制数是 120,对应的 ASCII 码字符是小写字母 “x”。在 ASCII 码表中,小写字母 “x” 的十进制 ASCII 码值为 120。因此,如果使用 write(int b) 方法写出一个字节值为 0x78(十进制为 120),那么写出的结果就是小写字母 “x”。

我们来验证一下:

FileOutputStream fos = null;
try {
    fos = new FileOutputStream("example.txt");

    fos.write(120);
    fos.write('x');
    fos.write(0x12345678);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (fos != null) {
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

来看一下结果:
在这里插入图片描述
果然是 3 个 x。

②、写入字节数组:write(byte[] b),代码示例:

// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");     
// 字符串转换为字节数组
byte[] b = "沉默王二有点帅".getBytes();
// 写入字节数组数据
fos.write(b);
// 关闭资源
fos.close();

③、写入指定长度字节数组:write(byte[] b, int off, int len),代码示例:

// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");     
// 字符串转换为字节数组
byte[] b = "abcde".getBytes();
// 从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b,2,2);
// 关闭资源
fos.close();

2.3FileOutputStream实现数据追加、换行

在上面的代码示例中,每次运行程序都会创建新的输出流对象,于是文件中的数据也会被清空。如果想保留目标文件中的数据,还能继续追加新数据,该怎么办呢?以及如何实现换行呢?

其实很简单。

我们来学习FileOutputStream的另外两个构造方法,如下:

  • 使用文件名和追加标志创建 FileOutputStream 对象
String fileName = "example.txt";
boolean append = true;
FileOutputStream fos = new FileOutputStream(fileName, append);

  • 使用文件对象和追加标志创建 FileOutputStream 对象
File file = new File("example.txt");
boolean append = true;
FileOutputStream fos = new FileOutputStream(file, append);

以上代码使用文件对象和追加标志创建一个 FileOutputStream 对象,将数据追加到该文件的末尾。

这两个构造方法,第二个参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示不追加也就是清空原有数据。

实现数据追加代码如下:

// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt",true);     
// 字符串转换为字节数组
byte[] b = "abcde".getBytes();
// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b);
// 关闭资源
fos.close();

多次运行代码,你会发现数据在不断地追加。

在 Windows 系统中,换行符号是\r\n,具体代码如下:

String filename = "example.txt";
FileOutputStream fos = new FileOutputStream(filename, true);  // 追加模式
String content = "张三\r\n";  // 使用回车符和换行符的组合
fos.write(content.getBytes());
fos.close();

在 macOS 系统中,换行符是 \n,具体代码如下:

String filename = "example.txt";
FileOutputStream fos = new FileOutputStream(filename, true);  // 追加模式
String content = "张三\n";  // 只使用换行符
fos.write(content.getBytes());
fos.close();

这里再唠一唠回车符和换行符。

回车符(\r)和换行符(\n)是计算机中常见的控制字符,用于表示一行的结束或者换行的操作。它们在不同的操作系统和编程语言中的使用方式可能有所不同。

在 Windows 系统中,通常使用回车符和换行符的组合(\r\n)来表示一行的结束。在文本文件中,每行的末尾都会以一个回车符和一个换行符的组合结束。这是由于早期的打印机和终端设备需要回车符和换行符的组合来完成一行的结束和换行操作。在 Windows 中,文本编辑器和命令行终端等工具都支持使用回车符和换行符的组合来表示一行的结束。

而在 macOS 和 Linux 系统中,通常只使用换行符(\n)来表示一行的结束。在文本文件中,每行的末尾只有一个换行符。这是由于早期 Unix 系统中的终端设备只需要换行符来完成一行的结束和跨行操作。在 macOS 和 Linux 中,文本编辑器和终端等工具都支持使用换行符来表示一行的结束。

在编程语言中,通常也会使用回车符和换行符来进行字符串的操作。例如,在 Java 中,字符串中的回车符可以用 “\r” 来表示,换行符可以用 “\n” 来表示。在通过输入输出流进行文件读写时,也需要注意回车符和换行符的使用方式和操作系统的差异。

3、字节流入流(InputStream)

java.io.InputStream 是字节输入流的超类(父类),我们来看一下它的一些共性方法:

  • close() :关闭此输入流并释放与此流相关的系统资源。

  • int read(): 从输入流读取数据的下一个字节。

  • read(byte[] b): 该方法返回的 int 值代表的是读取了多少个字节,读到几个返回几个,读取不到返回-1

4、FileInputStream类

InputStream 有很多子类,我们从最简单的一个子类 FileInputStream 开始。看名字就知道是文件输入流,用于将数据从文件中读取数据。

4.1FileInputStream的构造方法

  • FileInputStream(String name):创建一个 FileInputStream 对象,并打开指定名称的文件进行读取。文件名由 name 参数指定。如果文件不存在,将会抛出 FileNotFoundException 异常。

  • FileInputStream(File file):创建一个 FileInputStream 对象,并打开指定的 File 对象表示的文件进行读取。

代码示例如下:

// 创建一个 FileInputStream 对象
FileInputStream fis = new FileInputStream("test.txt");

// 读取文件内容
int data;
while ((data = fis.read()) != -1) {
    System.out.print((char) data);
}

// 关闭输入流
fis.close();

4.2FileInputStream读取字节数据

①、读取字节:read()方法会读取一个字节并返回其整数表示。如果已经到达文件的末尾,则返回 -1。如果在读取时发生错误,则会抛出 IOException 异常。

代码示例如下:

// 创建一个 FileInputStream 对象
FileInputStream fis = new FileInputStream("test.txt");

// 读取文件内容
int data;
while ((data = fis.read()) != -1) {
    System.out.print((char) data);
}

// 关闭输入流
fis.close();

②、使用字节数组读取:read(byte[] b) 方法会从输入流中最多读取 b.length 个字节,并将它们存储到缓冲区数组 b 中。

代码示例如下:

// 创建一个 FileInputStream 对象
FileInputStream fis = new FileInputStream("test.txt");

// 读取文件内容到缓冲区
byte[] buffer = new byte[1024];
int count;
while ((count = fis.read(buffer)) != -1) {
    System.out.println(new String(buffer, 0, count));
}

// 关闭输入流
fis.close();

4.3字节流FileInputstream复制图片

原理很简单,就是把图片信息读入到字节输入流中,再通过字节输出流写入到文件中。

代码示例如下所示:

// 创建一个 FileInputStream 对象以读取原始图片文件
FileInputStream fis = new FileInputStream("original.jpg");

// 创建一个 FileOutputStream 对象以写入复制后的图片文件
FileOutputStream fos = new FileOutputStream("copy.jpg");

// 创建一个缓冲区数组以存储读取的数据
byte[] buffer = new byte[1024];
int count;

// 读取原始图片文件并将数据写入复制后的图片文件
while ((count = fis.read(buffer)) != -1) {
    fos.write(buffer, 0, count);
}

// 关闭输入流和输出流
fis.close();
fos.close();

上面的代码创建了一个 FileInputStream 对象以读取原始图片文件,并创建了一个 FileOutputStream 对象以写入复制后的图片文件。然后,使用 while 循环逐个读取原始图片文件中的字节,并将其写入复制后的图片文件中。最后,关闭输入流和输出流释放资源。

5、小结

InputStream 是字节输入流的抽象类,它定义了读取字节数据的方法,如 read()、read(byte[] b)、read(byte[] b, int off, int len) 等。OutputStream 是字节输出流的抽象类,它定义了写入字节数据的方法,如 write(int b)、write(byte[] b)、write(byte[] b, int off, int len) 等。这两个抽象类是字节流的基础。

FileInputStream 是从文件中读取字节数据的流,它继承自 InputStream。FileOutputStream 是将字节数据写入文件的流,它继承自 OutputStream。这两个类是字节流最常用的实现类之一。

赠人玫瑰,收留余香,如果觉得有用,点个赞吧~~~~

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

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

相关文章

介绍自己的产品时,常犯的那些错

最近的一个轻咨询客户,在“全面提升组织产品能力”的项目中,正处于内部自学的“读书会”环节。 为了“用以致学”,而不是“学以致用”地读书,我给他们出了一道看起来很简单的题——介绍一下自己手头正在负责的产品。 前几天&#…

Java枚举

Java枚举 🍺1 背景及定义🍺🧃2 使用🧃🥤3 枚举优点缺点🥤🍵4 枚举和反射🍵🍷4.1 枚举是否可以通过反射,拿到实例对象呢?🍷 ☕️5 总结…

正负压力精密控制在隐形牙齿矫正器成型机中的应用

摘要:真空压力热成型技术作为一种精密成型工艺在诸如隐形牙套等制作领域得到越来越多的重视,其主要特点是要求采用高精度的正负压力控制手段来抵消重力对软化膜变形的影响以及精密控制成型膜厚度。本文提出了相应的改进解决方案,通过可编程的…

Greenplum数据库系统架构

Greenplum数据库系统架构 Greenplum是一个纯软件的MPP数据库服务器,其系统架构专门用于管理大规模分析型数据仓库或商业智能工作负载。从技术上讲,MPP无共享架构是指具有多个节点的系统,每个节点都有自己的内存、操作系统和磁盘,…

【天线专题】天线(Antenna)的理解

天线,英文名称是(Antenna),本义是指像蚂蚁、蜜蜂这样的小动物头顶上的触角。天线的作用就是将调制到射频频率的数字信号或模拟信号发射到空间无线信道,或从空间无线信道接收调制在射频频率上的数字或模拟信号。简单来说就是有发射和接收电磁波的功能。 所以两只蚂…

chatgpt赋能Python-python3_5怎么用

Python 3.5是什么? Python是一种高级编程语言,非常流行并广泛使用。Python3.5是Python编程语言的一个较新的版本,它具有许多新的功能和改进。Python 3.5已包含许多流行的Python框架。它可以用于各种任务,例如web开发,数据科学&a…

StableDiffusion模型发展历史

参考资料: 相应的github和huggingface LDM [github] StableDiffusion v1.1 ~ v1.4 [github] [huggingface] StableDiffusion v1.5 [huggingface] [github] StableDiffusion v2 v2.1 [github] [huggingface]   首先说一下,这篇文章的目的是让你清晰地了…

Django SQL注入漏洞 CVE-2022-28347

漏洞简介 在Django 2.2 的 2.2.28 之前版本、3.2 的 3.2.13 之前版本和 4.0 的 4.0.4 之前版本中的 QuerySet.deexplain() 中发现了SQL注入问题。这是通过传递一个精心编制的字典(带有字典扩展)作为**options参数来实现的,并将注入负载放置在…

[golang gin框架] 36.Gin 商城项目-RESTful API 设计指南,允许Cros跨域 ,提供api接口实现前后端分离,以及JWT的使用

一.RESTful API 设计指南 请看:Restful API 的接口规范 二.Gin 中配置服务器端允许跨域 github官方地址: https://github.com/gin-contrib/cors 在 main.go文件中配置跨域请求 代码如下: 在使用cors时,需要 引入该插件,先: import ( "github.com/gin-contrib/cors" )…

Cocos CreatorXR 1.2.0 今日发布,正式支持 WebXR ,并开启 MR 之路

去年九月,Cocos CreatorXR v1.0.1 版本支持了 VR 内容创作,成为率先支持 XR 的国产引擎,今年三月,Cocos CreatorXR v1.1.0 版本实现了对 AR 内容开发的支持。在完成基本功能的建设后,更多开发者开始尝试使用 Cocos Cre…

Linux内核oops panic简析

源码基于:Linux 5.4 0. 前言 内核异常的级别大致分为三个:BUG、oops、panic。 BUG 是指那些不符合内核的正常设计,但内核能够检测出来并且对系统运行不会产生影响的问题,比如在原子上下文中休眠,在内核中用 BUG 标识。…

case

[rootes3 data]# cat case11.sh #!/bin/bash. /etc/rc.d/init.d/functionsdisable_selinux(){sed -i s/SELNUXenforcing/SELINUXdisabled/ /etc/selinux/config action "SELINUX 已经禁用,重启生效" }disable_firewalld(){ systemctl disable --now firew…

chatgpt赋能Python-python3_9_1怎么打开

Python 3.9.1 使用指南:如何打开 Python 3.9.1 Python 3.9.1 是 Python 最新版本的一个分支,包含各种新特性和改进,能够让开发者快速、简单地创建并运行 Python 程序。如果您想要使用 Python 3.9.1,下面是一个简单的指南&#xf…

菜单选择shell

[rootes3 data]# vi action.sh #!/bin/bash . /etc/init.d/functionsecho -en "\E[$[RANDOM%731];1m"cat <<EOF请选择&#xff1a;1) 备份数据库2)清理日志3)软件升级4)软件回滚5)删库跑路EOFecho -en \E[0mread -p "请选择上面的项对应的数字1-5&#xf…

Spring Boot-如何让你的 bean 在其他 bean 之前完成加载

今天有个小伙伴给我出了一个难题&#xff1a;在 SpringBoot 中如何让自己的某个指定的 Bean 在其他 Bean 前完成被 Spring 加载&#xff1f;我听到这个问题的第一反应是&#xff0c;为什么会有这样奇怪的需求&#xff1f;Talk is cheap&#xff0c;show me the code&#xff0c…

「读书感悟系列」原则:应对变化中的世界秩序(达利欧)

作者 | gongyouliu 编辑 | gongyouliu 最近2个月读完了达利欧的『原则2&#xff1a;应对变化中的世界秩序』&#xff0c;收获非常大。几年之前读他的『原则1&#xff1a;工作与生活』就非常喜欢&#xff0c;很有启发&#xff0c;这次读起来一如既往的喜欢。这本书利用周期的思路…

Qt推流程序自动生成网页远程查看实时视频流(视频文件/视频流/摄像头/桌面转成流媒体rtmp+hls+webrtc)

一、前言说明 推流程序将视频流推送到流媒体服务器后&#xff0c;此时就等待验证拉流播放&#xff0c;一般可以选择ffplay命令行播放或者vlc等播放器打开播放&#xff0c;也可以选择网页直接打开拉流地址播放&#xff0c;一般主流的浏览器都支持网页直接播放hls/m3u8/webrtc类…

流批一体的近实时数仓的思考与设计

摘要&#xff1a;基于对数据时间旅行的思考&#xff0c;引出了对目前三种数仓形态和两种数仓架构的思考。结合数据湖在 Flink 的应用和数据湖元数据类型的思考&#xff0c;探索了基于数据湖的 Flink SQL 流批一体的实践&#xff0c;在流批一体 SQL 表达一致、结果一致性、流批任…

【JS】1686- 重学 JavaScript API - Clipboard API

&#x1f3dd; 1. 什么是 Clipboard API 1.1 概念介绍 Clipboard API[1] 是一组 JavaScript API&#xff0c;用于在浏览器中操作剪贴板。通过 Clipboard API&#xff0c;开发者可以将文本、图片和其他数据复制到剪贴板&#xff0c;也可以从剪贴板中读取数据&#xff0c;实现复制…

OPPO解散芯片团队的真相,真的不缺钱?

OPPO解散芯片研发团队&#xff0c;各方都喜欢说OPPO不缺钱&#xff0c;解散芯片研发团队应该不是因为资金问题&#xff0c;然而仔细看看当下全球智能手机市场的表现&#xff0c;就未必会如此想了。 全球手机市场的出货量在2022年下跌了12%&#xff0c;跌穿了12亿部&#xff1b;…