【Java 基础篇】Java 字节流详解:从入门到精通

Java中的字节流是处理二进制数据的关键工具之一。无论是文件操作、网络通信还是数据处理,字节流都发挥着重要作用。本文将从基础概念开始,深入探讨Java字节流的使用,旨在帮助初学者理解和掌握这一重要主题。
什么是字节流?
在Java中,字节流是以字节为单位进行输入和输出操作的一种流。字节流通常用于处理二进制数据,如图像、音频、视频文件等。Java提供了一组字节流类,分别用于输入和输出。常见的字节流类包括InputStream(输入流)和OutputStream(输出流)。
字节流的基本操作单元是字节(byte),这与字符流不同,字符流以字符为操作单元。由于字节流不关心数据的具体内容,因此它们适用于处理任何类型的文件。
让我们深入了解字节流的不同类型和用法。
字节输入流(InputStream)
字节输入流用于从数据源(如文件、网络连接、内存等)读取字节数据。Java提供了多种字节输入流的实现,下面是其中一些常用的。
FileInputStream
FileInputStream用于从文件中读取字节数据。它的构造函数接受文件路径作为参数,可以读取指定文件中的数据。
try (FileInputStream fis = new FileInputStream("example.txt")) {int data;while ((data = fis.read()) != -1) {// 处理读取的字节数据}
} catch (IOException e) {e.printStackTrace();
}
ByteArrayInputStream
ByteArrayInputStream用于从字节数组中读取数据。它的构造函数接受字节数组作为参数,可以读取字节数组中的数据。
byte[] byteArray = { 65, 66, 67, 68, 69 }; // ASCII码
try (ByteArrayInputStream bais = new ByteArrayInputStream(byteArray)) {int data;while ((data = bais.read()) != -1) {// 处理读取的字节数据}
} catch (IOException e) {e.printStackTrace();
}
其他输入流
除了上述两种,Java还提供了其他字节输入流,如BufferedInputStream用于带缓冲的输入、DataInputStream用于读取基本数据类型等。选择适当的输入流取决于你的需求和性能考虑。
字节输出流(OutputStream)
字节输出流用于将字节数据写入目标(如文件、网络连接、内存等)。与字节输入流类似,Java也提供了多种字节输出流的实现,以下是一些常见的。
FileOutputStream
FileOutputStream用于将字节数据写入文件。它的构造函数接受文件路径作为参数,可以将数据写入指定文件中。
try (FileOutputStream fos = new FileOutputStream("output.txt")) {byte[] data = { 72, 101, 108, 108, 111 }; // "Hello"的ASCII码fos.write(data);
} catch (IOException e) {e.printStackTrace();
}
ByteArrayOutputStream
ByteArrayOutputStream用于将
字节数据写入字节数组。它的构造函数不需要参数,数据将写入内部的字节数组中。
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {byte[] data = { 87, 111, 114, 108, 100 }; // "World"的ASCII码baos.write(data);byte[] result = baos.toByteArray();
} catch (IOException e) {e.printStackTrace();
}
其他输出流
除了上述两种,Java还提供了其他字节输出流,如BufferedOutputStream用于带缓冲的输出、DataOutputStream用于写入基本数据类型等。
文件操作
文件读取
使用FileInputStream可以方便地从文件中读取字节数据。以下是一个简单的文件读取示例:
try (FileInputStream fis = new FileInputStream("example.txt")) {int data;while ((data = fis.read()) != -1) {System.out.print((char) data); // 将字节数据转换为字符并打印}
} catch (IOException e) {e.printStackTrace();
}
文件写入
使用FileOutputStream可以将字节数据写入文件。以下是一个简单的文件写入示例:
try (FileOutputStream fos = new FileOutputStream("output.txt")) {byte[] data = { 72, 101, 108, 108, 111 }; // "Hello"的ASCII码fos.write(data);
} catch (IOException e) {e.printStackTrace();
}
异常处理
在处理字节流时,异常处理是非常重要的。可能会出现各种异常情况,如文件不存在、文件无法读取、磁盘已满等。因此,在使用字节流时,要确保适当地处理这些异常情况,以保证程序的稳定性。
try (FileInputStream fis = new FileInputStream("example.txt")) {int data;while ((data = fis.read()) != -1) {// 处理读取的字节数据}
} catch (FileNotFoundException e) {System.err.println("文件不存在:" + e.getMessage());
} catch (IOException e) {e.printStackTrace();
}
字节流的更多操作
当使用 Java 字节流进行数据处理时,除了基本的读取和写入操作,还存在一些更高级的操作,用以满足不同的需求。以下是一些常见的字节流更多操作:
1. 读取指定长度的字节
有时候,你可能需要从输入流中读取指定长度的字节数据。这可以通过 read(byte[] buffer, int offset, int length) 方法实现,其中 buffer 是用于存储读取数据的字节数组,offset 是数组起始位置的偏移量,length 是要读取的字节数。
try (FileInputStream fis = new FileInputStream("data.bin")) {byte[] buffer = new byte[1024]; // 缓冲区大小int bytesRead;while ((bytesRead = fis.read(buffer, 0, buffer.length)) != -1) {// 处理读取的字节数据}
} catch (IOException e) {e.printStackTrace();
}
2. 跳过指定数量的字节
有时候,你可能需要跳过输入流中的一些字节,而不处理它们。这可以通过 skip(long n) 方法实现,其中 n 是要跳过的字节数。
try (FileInputStream fis = new FileInputStream("data.bin")) {long bytesSkipped = fis.skip(10); // 跳过前面的10个字节// 继续处理后续的字节数据
} catch (IOException e) {e.printStackTrace();
}
3. 查找特定字节或字节数组
有时候,你可能需要在输入流中查找特定的字节或字节数组。这可以通过逐个字节或批量字节数据的方式实现。
查找特定字节
try (FileInputStream fis = new FileInputStream("data.bin")) {int targetByte = 42; // 要查找的字节值int data;while ((data = fis.read()) != -1) {if (data == targetByte) {// 找到目标字节,执行相应操作break;}}
} catch (IOException e) {e.printStackTrace();
}
查找特定字节数组
try (FileInputStream fis = new FileInputStream("data.bin")) {byte[] targetBytes = { 0x12, 0x34, 0x56 }; // 要查找的字节数组byte[] buffer = new byte[1024]; // 缓冲区大小int bytesRead;while ((bytesRead = fis.read(buffer)) != -1) {for (int i = 0; i < bytesRead; i++) {if (buffer[i] == targetBytes[0]) {// 找到第一个目标字节,检查后续字节是否匹配boolean match = true;for (int j = 1; j < targetBytes.length; j++) {if (i + j >= bytesRead || buffer[i + j] != targetBytes[j]) {match = false;break;}}if (match) {// 找到目标字节数组,执行相应操作break;}}}}
} catch (IOException e) {e.printStackTrace();
}
4. 复制字节流
有时候,你可能需要将一个字节流的内容复制到另一个地方,例如从一个文件复制到另一个文件。这可以通过读取一个字节流并将其写入另一个字节流来实现。
try (FileInputStream sourceStream = new FileInputStream("source.txt");FileOutputStream targetStream = new FileOutputStream("target.txt")) {byte[] buffer = new byte[1024]; // 缓冲区大小int bytesRead;while ((bytesRead = sourceStream.read(buffer)) != -1) {targetStream.write(buffer, 0, bytesRead);}
} catch (IOException e) {e.printStackTrace();
}
5. 使用 DataInputStream 和 DataOutputStream
DataInputStream 和 DataOutputStream 是用于读写基本数据类型(如整数、浮点数、布尔值等)的字节流,它们提供了方便的方法来读写这些数据类型,而不需要手动进行字节转换。
try (DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.dat"))) {int intValue = 42;double doubleValue = 3.14;boolean booleanValue = true;dos.writeInt(intValue);dos.writeDouble(doubleValue);dos.writeBoolean(booleanValue);
} catch (IOException e) {e.printStackTrace();
}try (DataInputStream dis = new DataInputStream(new FileInputStream("data.dat"))) {int intValue = dis.readInt();double doubleValue = dis.readDouble();boolean booleanValue = dis.readBoolean();// 使用读取到的数据
} catch (IOException e) {e.printStackTrace();
}
这些是 Java 字节流的一些更多操作,可根据具体需求来选择使用。字节流提供了灵活的方式来处理二进制数据,可应用于各种场景,包括文件操作、网络通信等。通过学习和实践这些操作,你可以更好地掌握字节流的使用,提高Java编程的效率。希望这些信息能够帮助你更好地理解和应用Java字节流。
注意事项
在使用Java字节流进行文件操作时,有一些注意事项需要考虑,以确保程序的正确性和可靠性。以下是一些常见的注意事项:
-
文件路径和文件名:确保文件路径和文件名是正确的。在指定文件路径时,使用适当的文件分隔符,以兼容不同操作系统。例如,使用
File.separator来获取适当的分隔符。String filePath = "C:" + File.separator + "myFolder" + File.separator + "myFile.txt"; -
文件是否存在:在打开或操作文件之前,应检查文件是否存在。可以使用
File.exists()方法来检查。File file = new File("myFile.txt"); if (file.exists()) {// 执行文件操作 } else {// 文件不存在,进行错误处理 } -
异常处理:文件操作可能会导致IOException等异常。必须使用
try-catch块来捕获并处理这些异常,以确保程序能够继续运行或进行适当的错误处理。try (FileInputStream fis = new FileInputStream("myFile.txt")) {// 执行文件读取操作 } catch (IOException e) {e.printStackTrace(); } -
资源管理:在使用字节流操作文件后,必须关闭流以释放资源。可以使用
try-with-resources语句来自动关闭流,以避免资源泄漏。try (FileInputStream fis = new FileInputStream("myFile.txt")) {// 执行文件读取操作 } catch (IOException e) {e.printStackTrace(); } -
字节顺序:在处理二进制数据时,特别是在不同平台之间传输二进制数据时,需要考虑字节顺序的问题。可以使用
DataInputStream和DataOutputStream等类来确保数据的正确序列化和反序列化。 -
缓冲:在大文件操作时,使用缓冲可以提高性能。可以考虑使用
BufferedInputStream和BufferedOutputStream来进行缓冲操作。try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myFile.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {// 执行文件复制操作 } catch (IOException e) {e.printStackTrace(); } -
文件锁定:在多线程或多进程环境中,确保文件不被其他程序同时访问可能很重要。你可以使用文件锁定机制来实现这一点。
try (FileLock lock = channel.lock()) {// 执行文件操作 } catch (IOException e) {e.printStackTrace(); } -
文件权限:确保在执行文件操作时,程序有足够的权限来读取或写入文件。如果没有足够的权限,可能会导致
SecurityException。
这些是使用Java字节流时需要注意的一些重要方面。根据具体的应用场景和需求,你可能需要进一步考虑其他因素,以确保文件操作的稳定性和可靠性。
总结
本文介绍了Java字节流的基本概念和常见用法,包括字节输入流和输出流的操作、文件读写以及异常处理。通过学习和实践,你可以更好地理解和运用字节流,处理各种二进制数据,从而提升Java编程的技能和效率。希望本文能够帮助你更好地掌握Java字节流的知识。
相关文章:
【Java 基础篇】Java 字节流详解:从入门到精通
Java中的字节流是处理二进制数据的关键工具之一。无论是文件操作、网络通信还是数据处理,字节流都发挥着重要作用。本文将从基础概念开始,深入探讨Java字节流的使用,旨在帮助初学者理解和掌握这一重要主题。 什么是字节流? 在Ja…...
Vue记录(下篇)
Vuex getters配置项 *Count.vue <template><div><h1>当前求和为:{{$store.state.sum}}</h1><h3>当前求和的10倍为:{{$store.getters.bigSum}}</h3><select v-model.number"n"><option value&q…...
【测试开发】概念篇 · 测试相关基础概念 · 常见开发模型 · 常见测试模型
【测试开发】概念篇 文章目录 【测试开发】概念篇1. 什么是需求1.1 需求的定义1.2 为什么有需求1.3 测试人员眼里的需求1.4 如何深入了解需求 2. 什么是测试用例2.1 为什么有测试用例2.2 练习>手机打电话 3. 什么是bug4. 开发模型和测试模型4.1 软件生命周期4.2 开发模型4.3…...
1. 快速体验 VSCode 和 CMake 创建 C/C++项目
1. 快速体验 VSCode 和 CMake 创建 C/C项目 本章的全部代码和markdown文件地址: CMake_Tutorial,欢迎互相交流. 此次介绍的内容都是针对于 Linux 操作系统上的开发过程. 1.1 安装开发工具 VSCode: 自行下载安装, 然后安装插件 Cmake:在 Ubuntu 系统上, 可以采用 ap…...
【JAVA-Day18】用大白话讲解 Java 中的内存机制
标题 用大白话讲解 Java 中的内存机制摘要引言一、Java 内存机制1.1 栈内存1.2 堆内存 二、Java 如何管理内存三、合理管理内存的必要性与其他方式相比优势劣势建议四、总结参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客👦🏻 《…...
[Hadoop] start-dfs.sh ssh报错
Permission denied (publickey 决解方案 相关命令 cd ~/.sshssh-keygen -t rsa -p""cat id_rsa.pub >> authorized_keyschmod 0600 authorized_keys 相关链接Hadoop: start-dfs.sh permission denied - Stack Overflow Java HotSpot(TM) Server VM warning…...
amlogic 多wifi 多bluetooh 兼容方案
WiFi部分: vendor/amlogic/common/wifi_bt/wifi/configs/wifi.mk 或者 hardware/amlogic/wifi/configs/wifi.mk ################################################################################## realtek wifi ifneq ($(filter rtl8188eu rtl8188ftv rtl8192eu rtl8…...
Apache Hive概述,模拟实现Hive功能,Hive基础架构
1、Apache Hive 概述 1.1、分布式SQL计算 对数据进行统计分析,SQL是目前最为方便的编程工具。 大数据体系中充斥着非常多的统计分析场景 所以,使用SQL去处理数据,在大数据中也是有极大的需求的。 MapReduce支持程序开发(Java…...
postgresql|数据库|centos7下基于postgresql-12的主从复制的pgpool-4.4的部署和使用
前言: postgresql数据库只用自身的一些配置是无法做到最优的优化的,需要通过一些外置插件(中间件)来提高服务器的整体性能,通俗的说就是数据库仅仅依靠自身是无法达到性能最优的,很多时候需要更改数据库的…...
python之pyQt5实例:PyQtGraph的应用
1、显示逻辑 "MainWindow": "这是主窗口,所有的其他组件都会被添加到这个窗口上。", "centralwidget": "这是主窗口的中心部件,它包含了其他的部件。","pushButton": "这是一个按钮,…...
Java——键盘输入的几种常见方式
Java——键盘输入的几种常见方式 文章目录: Java——键盘输入的几种常见方式一、IO流二、Scanner类三 、BufferedReader写入 一、IO流 在Java的输入中,是以输入流的形式进入程序,因此无法直接指定输入的类型,仅能读取键盘上的内容…...
Shell脚本中文英文多语言国际化和命令行批处理(bash sh cmd bat)中定义函数的简单写法
文章目录 命令行脚本参考 - bat命令行脚本参考 - bash值得学习的知识点1. 识别终端使用的语言2. 函数的编写3. 获取用户的输入4. bat文件老是乱码怎么办 有时候为了方便别人使用,我们会选择去编写各种各样的命令行脚本:给Windows用户编写.bat cmd批处理脚…...
stringBuffer.append(analyze);使用这个拼接时候如何在字符串参数字符串参数整数参数字符串数组参数内容之间添加空格
stringBuffer.append(analyze);使用这个拼接时候如何在字符串参数字符串参数整数参数字符串数组参数内容之间添加空格? 在添加参数到 StringBuffer 时,你可以在每次添加参数之后都添加一个空格,如下所示: StringBuffer stringBu…...
点云从入门到精通技术详解100篇-大范围田间场景 3D 点云语义分割研究(续)
目录 3.2 自制数据集展示 3.2.1 收集航拍图像 3.2.2 3D 点云重建 3.2.3 语义标签标注...
Mysql详解Explain索引优化最佳实践
目录 1 Explain工具介绍2 explain 两个变种3 explain中的列3.1 id列3.2 select_type列3.3 table列3.4. type列3.5 possible_keys列3.6 key列3.7 key_len列3.8 ref列3.9 rows列3.10 Extra列 4 索引最佳实践4.1.全值匹配4.2.最左前缀法则4.3.不在索引列上做任何操作(计…...
STM32H7 Azure RTOS
STM32H7 是意法半导体(STMicroelectronics)推出的一款高性能微控制器系列,基于 Arm Cortex-M7 内核。它具有丰富的外设和高性能计算能力,适用于各种应用领域。 Azure RTOS(原名 ThreadX)是一款实时操作系统…...
基于LUT查找表方法的图像gamma校正算法FPGA实现,包括tb测试文件和MATLAB辅助验证
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将gamma2.2和gamma1/2.2的数据分别导入到matlab进行对比: 2.算法运行软件版本 matlab2022a 3.部分核心程序 timescale 1ns / 1ps //…...
Function模块
0 Preface/Foreword 1 数据结构 1.1 func_cb_t //task control block typedef struct {u8 sta; //cur working task numberu8 last; //lask task number #if BT_BACKSTAGE_ENu8 sta_break…...
Prometheus PromQL数据查询语言
PromQL 简介 PromQL(Prometheus Query Language)是 Prometheus 内置的数据查询语言。支持用户进行实时的数据查询及聚合操作。 Prometheus 基于指标名称(metrics name)以及附属的标签集(labelset)唯一定义一…...
如何将转换器应用于时序模型
一、说明 在机器学习的广阔环境中,变压器作为建筑奇迹屹立不倒,以其复杂的设计和捕获复杂关系的能力重塑了我们处理和理解大量数据的方式。 自 2017 年创建第一台变压器以来,变压器类型呈爆炸式增长,包括强大的生成 AI 模型&#…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果