当前位置: 首页 > news >正文

【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. 使用 DataInputStreamDataOutputStream

DataInputStreamDataOutputStream 是用于读写基本数据类型(如整数、浮点数、布尔值等)的字节流,它们提供了方便的方法来读写这些数据类型,而不需要手动进行字节转换。

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字节流进行文件操作时,有一些注意事项需要考虑,以确保程序的正确性和可靠性。以下是一些常见的注意事项:

  1. 文件路径和文件名:确保文件路径和文件名是正确的。在指定文件路径时,使用适当的文件分隔符,以兼容不同操作系统。例如,使用File.separator来获取适当的分隔符。

    String filePath = "C:" + File.separator + "myFolder" + File.separator + "myFile.txt";
    
  2. 文件是否存在:在打开或操作文件之前,应检查文件是否存在。可以使用File.exists()方法来检查。

    File file = new File("myFile.txt");
    if (file.exists()) {// 执行文件操作
    } else {// 文件不存在,进行错误处理
    }
    
  3. 异常处理:文件操作可能会导致IOException等异常。必须使用try-catch块来捕获并处理这些异常,以确保程序能够继续运行或进行适当的错误处理。

    try (FileInputStream fis = new FileInputStream("myFile.txt")) {// 执行文件读取操作
    } catch (IOException e) {e.printStackTrace();
    }
    
  4. 资源管理:在使用字节流操作文件后,必须关闭流以释放资源。可以使用try-with-resources语句来自动关闭流,以避免资源泄漏。

    try (FileInputStream fis = new FileInputStream("myFile.txt")) {// 执行文件读取操作
    } catch (IOException e) {e.printStackTrace();
    }
    
  5. 字节顺序:在处理二进制数据时,特别是在不同平台之间传输二进制数据时,需要考虑字节顺序的问题。可以使用DataInputStreamDataOutputStream等类来确保数据的正确序列化和反序列化。

  6. 缓冲:在大文件操作时,使用缓冲可以提高性能。可以考虑使用BufferedInputStreamBufferedOutputStream来进行缓冲操作。

    try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myFile.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) {// 执行文件复制操作
    } catch (IOException e) {e.printStackTrace();
    }
    
  7. 文件锁定:在多线程或多进程环境中,确保文件不被其他程序同时访问可能很重要。你可以使用文件锁定机制来实现这一点。

    try (FileLock lock = channel.lock()) {// 执行文件操作
    } catch (IOException e) {e.printStackTrace();
    }
    
  8. 文件权限:确保在执行文件操作时,程序有足够的权限来读取或写入文件。如果没有足够的权限,可能会导致SecurityException

这些是使用Java字节流时需要注意的一些重要方面。根据具体的应用场景和需求,你可能需要进一步考虑其他因素,以确保文件操作的稳定性和可靠性。

总结

本文介绍了Java字节流的基本概念和常见用法,包括字节输入流和输出流的操作、文件读写以及异常处理。通过学习和实践,你可以更好地理解和运用字节流,处理各种二进制数据,从而提升Java编程的技能和效率。希望本文能够帮助你更好地掌握Java字节流的知识。

相关文章:

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

Java中的字节流是处理二进制数据的关键工具之一。无论是文件操作、网络通信还是数据处理&#xff0c;字节流都发挥着重要作用。本文将从基础概念开始&#xff0c;深入探讨Java字节流的使用&#xff0c;旨在帮助初学者理解和掌握这一重要主题。 什么是字节流&#xff1f; 在Ja…...

Vue记录(下篇)

Vuex getters配置项 *Count.vue <template><div><h1>当前求和为&#xff1a;{{$store.state.sum}}</h1><h3>当前求和的10倍为&#xff1a;{{$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&#xff0c;欢迎互相交流. 此次介绍的内容都是针对于 Linux 操作系统上的开发过程. 1.1 安装开发工具 VSCode: 自行下载安装, 然后安装插件 Cmake:在 Ubuntu 系统上, 可以采用 ap…...

【JAVA-Day18】用大白话讲解 Java 中的内存机制

标题 用大白话讲解 Java 中的内存机制摘要引言一、Java 内存机制1.1 栈内存1.2 堆内存 二、Java 如何管理内存三、合理管理内存的必要性与其他方式相比优势劣势建议四、总结参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#x1f466;&#x1f3fb; 《…...

[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计算 对数据进行统计分析&#xff0c;SQL是目前最为方便的编程工具。 大数据体系中充斥着非常多的统计分析场景 所以&#xff0c;使用SQL去处理数据&#xff0c;在大数据中也是有极大的需求的。 MapReduce支持程序开发&#xff08;Java…...

postgresql|数据库|centos7下基于postgresql-12的主从复制的pgpool-4.4的部署和使用

前言&#xff1a; postgresql数据库只用自身的一些配置是无法做到最优的优化的&#xff0c;需要通过一些外置插件&#xff08;中间件&#xff09;来提高服务器的整体性能&#xff0c;通俗的说就是数据库仅仅依靠自身是无法达到性能最优的&#xff0c;很多时候需要更改数据库的…...

python之pyQt5实例:PyQtGraph的应用

1、显示逻辑 "MainWindow": "这是主窗口&#xff0c;所有的其他组件都会被添加到这个窗口上。", "centralwidget": "这是主窗口的中心部件&#xff0c;它包含了其他的部件。","pushButton": "这是一个按钮&#xff0c…...

Java——键盘输入的几种常见方式

Java——键盘输入的几种常见方式 文章目录&#xff1a; Java——键盘输入的几种常见方式一、IO流二、Scanner类三 、BufferedReader写入 一、IO流 在Java的输入中&#xff0c;是以输入流的形式进入程序&#xff0c;因此无法直接指定输入的类型&#xff0c;仅能读取键盘上的内容…...

Shell脚本中文英文多语言国际化和命令行批处理(bash sh cmd bat)中定义函数的简单写法

文章目录 命令行脚本参考 - bat命令行脚本参考 - bash值得学习的知识点1. 识别终端使用的语言2. 函数的编写3. 获取用户的输入4. bat文件老是乱码怎么办 有时候为了方便别人使用&#xff0c;我们会选择去编写各种各样的命令行脚本&#xff1a;给Windows用户编写.bat cmd批处理脚…...

stringBuffer.append(analyze);使用这个拼接时候如何在字符串参数字符串参数整数参数字符串数组参数内容之间添加空格

stringBuffer.append(analyze);使用这个拼接时候如何在字符串参数字符串参数整数参数字符串数组参数内容之间添加空格&#xff1f; 在添加参数到 StringBuffer 时&#xff0c;你可以在每次添加参数之后都添加一个空格&#xff0c;如下所示&#xff1a; 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.不在索引列上做任何操作&#xff08;计…...

STM32H7 Azure RTOS

STM32H7 是意法半导体&#xff08;STMicroelectronics&#xff09;推出的一款高性能微控制器系列&#xff0c;基于 Arm Cortex-M7 内核。它具有丰富的外设和高性能计算能力&#xff0c;适用于各种应用领域。 Azure RTOS&#xff08;原名 ThreadX&#xff09;是一款实时操作系统…...

基于LUT查找表方法的图像gamma校正算法FPGA实现,包括tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将gamma2.2和gamma1/2.2的数据分别导入到matlab进行对比&#xff1a; 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&#xff08;Prometheus Query Language&#xff09;是 Prometheus 内置的数据查询语言。支持用户进行实时的数据查询及聚合操作。 Prometheus 基于指标名称&#xff08;metrics name&#xff09;以及附属的标签集&#xff08;labelset&#xff09;唯一定义一…...

如何将转换器应用于时序模型

一、说明 在机器学习的广阔环境中&#xff0c;变压器作为建筑奇迹屹立不倒&#xff0c;以其复杂的设计和捕获复杂关系的能力重塑了我们处理和理解大量数据的方式。 自 2017 年创建第一台变压器以来&#xff0c;变压器类型呈爆炸式增长&#xff0c;包括强大的生成 AI 模型&#…...

nli-distilroberta-base生产环境:金融风控中合同条款中立性识别实践

nli-distilroberta-base生产环境&#xff1a;金融风控中合同条款中立性识别实践 1. 项目背景与价值 在金融风控领域&#xff0c;合同条款的准确理解至关重要。传统人工审核方式效率低下且容易遗漏关键细节&#xff0c;而自然语言理解技术可以大幅提升审核效率和准确性。nli-d…...

BepInEx游戏插件加载器完全指南:从入门到精通Unity游戏扩展工具

BepInEx游戏插件加载器完全指南&#xff1a;从入门到精通Unity游戏扩展工具 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx 如何用BepInEx解锁游戏自定义功能&#xff1f;解决玩家…...

2026降AI率工具红黑榜:降AI率网站怎么选?看完少走弯路

千笔AI、ThouPen、豆包位列红榜&#xff0c;精准适配国内高校AI率检测规范&#xff1b;黑榜需避开低质免费工具、无正规检测对接平台及改写痕迹明显的工具&#xff1b;选择时应优先匹配三维模型&#xff1a;降AI效果-学术合规性-使用成本。 一、红榜&#xff1a;10 款高分论文降…...

离散数学实战:用Python解决图论问题(附完整代码示例)

离散数学实战&#xff1a;用Python解决图论问题&#xff08;附完整代码示例&#xff09; 当你在社交软件上查看"可能认识的人"推荐&#xff0c;或是用导航软件规划最短路线时&#xff0c;背后都在运行图论算法。作为离散数学中最具工程价值的领域&#xff0c;图论将现…...

新型电力系统数据底座选型:源网荷储四侧时序数据库实战应用

文章目录 一、新型电力系统到底哪里变了&#xff1f;二、电力新业态带来的数字化挑战首先是采集数据的挑战其次是关于实时性的挑战最后是关于计算复杂度的挑战 三、新需求下传统架构已显疲态数据存储割裂实时计算与离线分析的割裂计算引擎分散&#xff0c;维护成本高规则变化时…...

Nginx反向代理实战:不改代码轻松解决前后端跨域问题(附完整配置模板)

Nginx反向代理实战&#xff1a;不改代码轻松解决前后端跨域问题&#xff08;附完整配置模板&#xff09; 前后端分离架构已成为现代Web开发的主流模式&#xff0c;但随之而来的跨域问题却让不少开发者头疼。想象一下这样的场景&#xff1a;你的前端运行在https://frontend.com&…...

OpenClaw数据安全实践:Qwen3-32B+RTX4090D本地化处理敏感财报

OpenClaw数据安全实践&#xff1a;Qwen3-32BRTX4090D本地化处理敏感财报 1. 为什么金融从业者需要本地化AI处理 去年我在帮一家私募基金做季度财报分析时&#xff0c;遇到了一个尴尬场景&#xff1a;当我把客户PDF财报上传到某公有云AI平台提取关键指标后&#xff0c;第二天就…...

ESP32开发实战:5分钟搞定MicroPython调用C库驱动LED(附完整代码)

ESP32混合编程实战&#xff1a;用MicroPython调用C库实现高性能LED控制 在物联网设备开发中&#xff0c;ESP32凭借其出色的性价比和丰富的功能接口成为硬件开发者的首选。而MicroPython作为嵌入式领域的Python实现&#xff0c;以其简洁的语法和快速的开发周期赢得了大量开发者的…...

Phi-3-Mini-128K企业级应用:基于MCP协议构建安全可控的AI工具链

Phi-3-Mini-128K企业级应用&#xff1a;基于MCP协议构建安全可控的AI工具链 最近和几个在企业里做技术管理的朋友聊天&#xff0c;大家不约而同地提到了同一个烦恼&#xff1a;看着外面各种AI模型能力越来越强&#xff0c;心里痒痒的&#xff0c;真想引入到自己的业务流程里&a…...

Save Image as Type:终极Chrome图片格式转换指南,三步快速解决网页图片格式不兼容难题

Save Image as Type&#xff1a;终极Chrome图片格式转换指南&#xff0c;三步快速解决网页图片格式不兼容难题 【免费下载链接】Save-Image-as-Type Save Image as Type is an chrome extension which add Save as PNG / JPG / WebP to the context menu of image. 项目地址:…...