Java IO流学习指南:从小白到入门

Java的IO(Input/Output)流是处理数据输入和输出的基础。无论是读取文件、写入文件,还是通过网络传输数据,IO流都无处不在。对于刚接触Java的新手,理解IO流可能会有些困惑,但别担心,今天我们将一步步走过它,让你从一个小白变成IO流的小达人!


一、什么是IO流?

在Java中,IO流是指数据流向的方向,它包括了输入流(InputStream)和输出流(OutputStream)两大类。

  • 输入流(InputStream):用于读取数据的流,例如从文件、键盘或网络中读取数据。

  • 输出流(OutputStream):用于向目标写入数据的流,比如将数据写入文件、控制台或网络中。

IO流的核心概念就是“数据流向”,可以理解为你从某个地方读取数据,或者将数据写入到某个地方。


二、IO流的分类

Java中的IO流有很多种,按用途大致可以分为两大类:

  1. 字节流(Byte Stream):处理所有类型的I/O,适用于所有类型的数据(包括图片、音频、视频等二进制数据)。字节流的父类是 InputStreamOutputStream

  2. 字符流(Character Stream):专门用于处理文本数据(即字符数据),它是对字节流的封装,采用字符编码方式来读取和写入文本数据。字符流的父类是 ReaderWriter


详细解释

所谓这些流就是一个链接文件的管道,字节,字符流,就是代表在管道里面流转的数据不一样输入流就是将文件内容通过管道发送到程序。输出流就是从程序写入到文件里面。流的分类按照流的方向:输入流、输出流按照流的内容:字节流、字符流
字节流:适合操作所有类型的文件 字符流:适合操作纯文本文件
他们之间组合形成了四个类
字节输入流 FileInputStream
字符输出流 FileOutputStream
字符输入流 FileReader
字符输出流 FileWriter他们都继承两个基类 InputStream  OutputStream他们本质就是一些对象,拥有一些操作数据的方法。
创建对象
字节输入流为例
FileOutputStream fos = new FileOutputStream("文件路径");
其他就是替换类名就行了。也可以利用多态写法,换成基类
注意:绝对路径和相对路径的差别,在开发多人项目的时候一般使用相对路径,就是在你的项目中的路径。
绝对路径就是存放在磁盘的路径,但当你拿别人的项目的时候一旦文件存放的磁盘不一样就会抛出异常。方法:字符和字节一样都有方法
读入方法,单个字节读入int b = fos.read();int b;while((b=is.read())!=-1){System.out.print((char)b);}
这样效率非常慢,而且不能存放汉字,因为一个汉字的字节占位不是一,
我们一般利用数组传入,一次性传多个byte[] buffer = new byte[5];
int len;//定义一个变量记住每次读取了多少个字节,因为有可能都不满数组。
while((len=is.read(buffer))!=-1){  System.out.print(new String(buffer,0,len));//解释一下,len是每次读取的字节数,//即从0开始,截取len个字节,转换成字符串输出//String  s = new String(buffer);// System.out.println(s);//这样写的话,每次都会将buffer中的字节全部转换成字符串,如果源文件只有4个字节,那么就会将buffer中多余的字节转换成乱码        //但是无法解决乱码问题。//解决方法,一次读完所以的字节,只适合小文件,大文件可能会造成内存溢出//readAllBytes()//读取文件所有字节//byte[] bytes = is.readAllBytes();//System.out.println(new String(bytes));
 文件字节输出流 FileOutputStream作用:将数据写入文件覆盖管道,会覆盖原来的数据FileOutputStream fos = new FileOutputStream("路径");//与字节输入流一样,也有一个字节输出流管道与源文件路径接通//FileOutputStream(File file)//与源文件路径接通(一般用)//FileOutputStream(String path)//写数据文件会自动创建文件FileOutputStream fos = new FileOutputStream("file_io_stream\\src\\text02.txt");//同样的文件字节输出流也有将读到文件里面的方法,但是和输入流也存在乱码问题,解决方式也一样//一个字节写入一个字节 write()fos.write('9');//也有数组方式byte[] bytess = {97,98,99,100};//将文字编码成字节byte[] bytesss = "我爱中国".getBytes();fos.write(bytesss);fos.write(bytess);//也能写一部分字节数组出去//将字节1-2写出去//但是在写汉字的时候依然会有乱码问题//write(字节数组,起始位置,写多少个字节出去)fos.write(bytesss,0,9);//但是这样写是将文件清空在写的,所以不能重复写入。//要追加添加文件,需要使用带参数的构造方法//追加参数,追加数据FileOutputStream fos1 = new FileOutputStream("file_io_stream\\src\\text02.txt",true);//注意在这些流用完后一定要关闭流fos.close();fos1.close();

 但是我们流在使用后必须关闭,但是一定程序在流关闭之前就抛出异常,导致流没有关闭,造成内存泄漏所以我们规定了流的写法格式

try(){

}catch()

{

}

 try(只能放置资源对象,用完后最终会自动调用close方法FileInputStream fis=new FileInputStream(src);FileOutputStream fos=new FileOutputStream(dest,true);){byte[] buf=new byte[1024];int len;while((len=fis.read(buf))!=-1){fos.write(buf,0,len);//读取多少字节就写多少字节}}catch (Exception e){e.printStackTrace();}}

 字符和字节完全一样,只是方法的名称有些不一样

读入

 try( FileReader fr = new FileReader("file_io_stream\\src\\zi_fu_stream\\zi_fu_text");){char [] cbuf = new char[1024];//不建议单个字符读入,会拖累程序int b;while((b = fr.read(cbuf)) != -1){//打印出来System.out.print(new String(cbuf,0,b));}//字符没有全部读入方式//拓展:文件字符输入流每次读多个字符,性能较好,而且读中文没有乱码}catch (Exception e){e.printStackTrace();}

输出

//五个方法//write(char c)//写入一个字符//write(String str)//写入一个字符串//write(char[] cbuf)//写入一个字符数组//write(char[] cbuf,int off,int len)//写入一个字符数组的一部分//flush()//刷新缓冲区,将数据写入文件

 我们一般就使用字符串 

缓冲流

 认识缓冲流缓冲字节输入流 BufferedInputStream缓冲字节输出流BufferedOutputStream缓冲字符输入流 BufferedReader缓冲字符输出流 BufferedWriter

其实就是提高性能而且,在外面套了一层壳使用方法一模一样就是换了类名

字符缓冲输入流新增功能:按照行读取字符
        try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {String line;while ((line = reader.readLine()) != null) {// 处理每一行}} catch (IOException e) {e.printStackTrace();}

三、简单的字节流示例

先从一个最基础的例子开始:用字节流读取和写入文件。

1. 读取文件内容
import java.io.FileInputStream;
import java.io.IOException;
​
public class FileReaderExample {public static void main(String[] args) {try (FileInputStream fis = new FileInputStream("input.txt")) {int byteData;while ((byteData = fis.read()) != -1) {System.out.print((char) byteData);}} catch (IOException e) {e.printStackTrace();}}
}

解释:

  • FileInputStream 是字节流的一个例子,用来读取文件数据。

  • fis.read() 方法逐个字节读取文件的内容。

  • try-with-resources 语法可以自动关闭资源,避免手动关闭。

2. 写入文件内容
import java.io.FileOutputStream;
import java.io.IOException;
​
public class FileWriterExample {public static void main(String[] args) {try (FileOutputStream fos = new FileOutputStream("output.txt")) {String message = "Hello, Java IO!";fos.write(message.getBytes());  // 将字符串转换为字节数组并写入文件} catch (IOException e) {e.printStackTrace();}}
}

解释:

  • FileOutputStream 用于将数据写入文件。

  • write() 方法将字节数据写入文件。


四、简单的字符流示例

字符流适用于文本文件的读取和写入,它会自动进行字符编码的转换。

1. 读取文本文件
import java.io.FileReader;
import java.io.IOException;
​
public class FileReaderExample {public static void main(String[] args) {try (FileReader fr = new FileReader("input.txt")) {int charData;while ((charData = fr.read()) != -1) {System.out.print((char) charData);  // 输出每个字符}} catch (IOException e) {e.printStackTrace();}}
}
2. 写入文本文件
import java.io.FileWriter;
import java.io.IOException;
​
public class FileWriterExample {public static void main(String[] args) {try (FileWriter fw = new FileWriter("output.txt")) {String message = "Hello, Java IO with Character Streams!";fw.write(message);  // 直接写入字符串} catch (IOException e) {e.printStackTrace();}}
}

五、常用的IO流类和方法

  • FileInputStream/FileOutputStream:用于字节流读写文件。

  • FileReader/FileWriter:用于字符流读写文件。

  • BufferedReader/BufferedWriter:用于高效地读取和写入字符数据,适合处理大量文本数据。

1. 使用 BufferedReader 读取文件
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
​
public class BufferedReaderExample {public static void main(String[] args) {try (BufferedReader br = new BufferedReader(new FileReader("input.txt"))) {String line;while ((line = br.readLine()) != null) {System.out.println(line);  // 逐行读取文件内容}} catch (IOException e) {e.printStackTrace();}}
}
2. 使用 BufferedWriter 写入文件
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
​
public class BufferedWriterExample {public static void main(String[] args) {try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) {String message = "Buffered Writer Example";bw.write(message);  // 写入内容} catch (IOException e) {e.printStackTrace();}}
}

六、IO流的实际应用场景

  1. 读取和写入文件:最常见的应用,比如读取配置文件、写入日志文件等。

  2. 网络通信:通过Socket连接进行网络数据的发送和接收。

  3. 数据加密与解密:处理加密文件的读取和写入。

  4. 多线程并发访问文件:使用IO流结合多线程技术,处理并发文件操作。


最后介绍一下io框架

commons-io.jar

为了简化上面的方法,io框架将上面的内容封装成了一个个内容,方便我们直接调用,说白了上面学了都没用,直接用框架就行,但是我们还是要掌握数据流动的方式。

1. IOUtils

处理输入/输出流的工具类。

方法列表与作用
方法作用
copy(InputStream, OutputStream)复制输入流到输出流(自动缓冲)
toString(InputStream, Charset)将输入流内容转为字符串
readLines(InputStream, Charset)按行读取输入流为字符串列表
示例代码
import org.apache.commons.io.IOUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
​
public class IOUtilsExample {public static void main(String[] args) throws IOException {// 1. 复制流try (InputStream in = new FileInputStream("input.txt");OutputStream out = new FileOutputStream("output.txt")) {IOUtils.copy(in, out); // 将 input.txt 内容复制到 output.txt}
​// 2. 输入流转字符串try (InputStream in = new FileInputStream("input.txt")) {String content = IOUtils.toString(in, StandardCharsets.UTF_8);System.out.println(content); // 输出文件内容}
​// 3. 按行读取try (InputStream in = new FileInputStream("input.txt")) {List<String> lines = IOUtils.readLines(in, StandardCharsets.UTF_8);lines.forEach(System.out::println); // 逐行打印}}
}

2. FileUtils

文件操作工具类。

方法列表与作用
方法作用
readFileToString(File, Charset)读取文件内容为字符串
writeStringToFile(File, String, Charset)将字符串写入文件
copyFile(File, File)复制文件
copyDirectory(File, File)复制整个目录
deleteDirectory(File)递归删除目录
cleanDirectory(File)清空目录内容
示例代码
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.charset.StandardCharsets;
​
public class FileUtilsExample {public static void main(String[] args) throws IOException {// 1. 读取文件为字符串String content = FileUtils.readFileToString(new File("test.txt"), StandardCharsets.UTF_8);System.out.println(content);
​// 2. 写入字符串到文件FileUtils.writeStringToFile(new File("output.txt"), "Hello Commons IO", StandardCharsets.UTF_8);
​// 3. 复制文件FileUtils.copyFile(new File("source.txt"), new File("dest.txt"));
​// 4. 复制目录FileUtils.copyDirectory(new File("srcDir"), new File("destDir"));
​// 5. 删除目录FileUtils.deleteDirectory(new File("oldDir"));
​// 6. 清空目录FileUtils.cleanDirectory(new File("tempDir"));}
}

3. FilenameUtils

文件路径处理工具类。

方法列表与作用
方法作用
getExtension(String)获取文件扩展名
removeExtension(String)移除文件扩展名
concat(String, String)安全拼接路径
示例代码
import org.apache.commons.io.FilenameUtils;
​
public class FilenameUtilsExample {public static void main(String[] args) {// 1. 获取扩展名String ext = FilenameUtils.getExtension("data.json"); // 返回 "json"
​// 2. 移除扩展名String name = FilenameUtils.removeExtension("image.jpg"); // 返回 "image"
​// 3. 路径拼接String fullPath = FilenameUtils.concat("/home/user", "docs/file.txt"); // 返回 "/home/user/docs/file.txt"
​System.out.println(ext + ", " + name + ", " + fullPath);}
}

4. FileAlterationObserver

监控文件/目录变化的工具。

方法作用
  • 监听文件创建、修改、删除事件。

示例代码
import org.apache.commons.io.monitor.*;
import java.io.File;
​
public class FileMonitorExample {public static void main(String[] args) throws Exception {File dir = new File("monitored_dir");FileAlterationObserver observer = new FileAlterationObserver(dir);observer.addListener(new FileAlterationListenerAdaptor() {@Overridepublic void onFileCreate(File file) {System.out.println("文件创建: " + file.getName());}@Overridepublic void onFileDelete(File file) {System.out.println("文件删除: " + file.getName());}});
​FileAlterationMonitor monitor = new FileAlterationMonitor(1000); // 轮询间隔1秒monitor.addObserver(observer);monitor.start();
​// 保持程序运行(实际应用可能需要线程管理)Thread.sleep(60_000);monitor.stop();}
}

关键说明

//这里涉及到Maven工程管理,意思就是在idea里面下载这个jar包,方便自己使用,可以在我的博客里面找有关于Maven工程的介绍

  1. 依赖引入:需在项目中添加 Commons IO 依赖(如 Maven):

    <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.13.0</version>
    </dependency>
  2. 异常处理:所有示例需处理 IOException(此处简化为 throws)。

  3. 资源释放:使用 try-with-resources 确保流自动关闭。

通过这些示例,可以快速实现文件操作、流处理及目录监控功能。

七、总结

Java的IO流非常强大且灵活,掌握了它,你就能轻松地处理文件、网络等数据输入输出操作。虽然刚开始可能有些晦涩,但通过不断的实践和理解,你会逐步熟悉并掌握这些技术。

如果你有其他问题或需要更详细的案例,随时留言!希望这篇博客能帮助你顺利入门Java IO流。


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

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

相关文章

【后端高阶面经:微服务篇】1、微服务架构核心:服务注册与发现之AP vs CP选型全攻略

一、CAP理论在服务注册与发现中的落地实践 1.1 CAP三要素的技术权衡 要素AP模型实现CP模型实现一致性最终一致性&#xff08;Eureka通过异步复制实现&#xff09;强一致性&#xff08;ZooKeeper通过ZAB协议保证&#xff09;可用性服务节点可独立响应&#xff08;支持分区存活…

QNAP NEXTCLOUD 域名访问

我是用docker compose方式安装的&#xff0c;虽然不知道是不是这么个叫法&#xff0c;废话不多说。 背景&#xff1a;威联通container station安装了nextcloud和lucky&#xff0c;lucky进行的域名解析和反代 先在想安装的路径、数据存储路径、数据库路径等新建文件夹。再新建…

高级SQL技巧:窗口函数与复杂查询优化实战

高级SQL技巧&#xff1a;窗口函数与复杂查询优化实战 开篇&#xff1a;数据库开发中的挑战 在现代企业级应用中&#xff0c;数据库不仅是存储数据的核心组件&#xff0c;更是处理复杂业务逻辑的重要工具。然而&#xff0c;随着数据量和并发请求的不断增长&#xff0c;传统的S…

《STL--list的使用及其底层实现》

引言&#xff1a; 上次我们学习了容器vector的使用及其底层实现&#xff0c;今天我们再来学习一个容器list&#xff0c; 这里的list可以参考我们之前实现的单链表&#xff0c;但是这里的list是双向循环带头链表&#xff0c;下面我们就开始list的学习了。 一&#xff1a;list的…

docker中使用openresty

1.为什么要使用openresty 我这边是因为要使用1Panel&#xff0c;第一个最大的原因&#xff0c;就是图方便&#xff0c;比较可以一键安装。但以前一直都是直接安装nginx。所以需要一个过度。 2.如何查看openResty使用了nginx哪个版本 /usr/local/openresty/nginx/sbin/nginx …

vscode包含工程文件路径

在 VSCode 中配置 includePath 以自动识别并包含上层目录及其所有子文件夹&#xff0c;需结合通配符和相对/绝对路径实现。以下是具体操作步骤及原理说明&#xff1a; 1. 使用通配符 ** 递归包含所有子目录 在 c_cpp_properties.json 的 includePath 中&#xff0c;${workspac…

【排序算法】典型排序算法 Java实现

以下是典型的排序算法分类及对应的 Java 实现&#xff0c;包含时间复杂度、稳定性说明和核心代码示例&#xff1a; 一、比较类排序&#xff08;通过元素比较&#xff09; 1. 交换排序 ① 冒泡排序 时间复杂度&#xff1a;O(n)&#xff08;优化后最优O(n)&#xff09; 稳定性&…

多模态大语言模型arxiv论文略读(八十七)

MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ➡️ 论文标题&#xff1a;MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ➡️ 论文作者&#xff1a;Xiangyu Zhao, Xiangtai Li, Haodong Duan, Haian Huang, Yining Li, Kai Chen, Hua Ya…

塔能节能平板灯:点亮苏州某零售工厂节能之路

在苏州某零售工厂的运营成本中&#xff0c;照明能耗占据着一定比例。为降低成本、提升能源利用效率&#xff0c;该工厂与塔能科技携手&#xff0c;引入塔能节能平板灯&#xff0c;开启了精准节能之旅&#xff0c;并取得了令人瞩目的成效。 一、工厂照明能耗困境 苏州该零售工厂…

数据库事务的四大特性(ACID)

一、前言 在现代数据库系统中&#xff0c;事务&#xff08;Transaction&#xff09;是确保数据一致性和完整性的重要机制。事务的四大特性——原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;…

8 种快速易用的Python Matplotlib数据可视化方法

你是否曾经面对一堆复杂的数据&#xff0c;却不知道如何让它们变得直观易懂&#xff1f;别慌&#xff0c;Python 的 Matplotlib 库是你数据可视化的最佳伙伴&#xff01;它简单易用、功能强大&#xff0c;能将枯燥的数字变成引人入胜的图表。无论是学生、数据分析师还是程序员&…

springboot 控制层调用业务逻辑层,注入报错,无法自动装配 解决办法

报错&#xff1a; 解决&#xff1a;愿意是业务逻辑层&#xff0c;即service层的具体实现类没有加注解Service导致的&#xff0c;加上解决了&#xff01;&#xff01;

如何提高独立服务器的安全性?

独立服务器相对于其它服务器来说&#xff0c;整体的硬件设备都是独立的同时还有着强大的服务器性能&#xff0c;其中CPU设备能够决定着服务器的运算能力&#xff0c;所以独立服务器的安全性受到企业格外的重视&#xff0c;严重的话会给企业造成巨大的资金损失。 那么&#xff0…

关于 Web 风险点原理与利用:6. 逻辑风险点

一、分类&#xff1a; 1.1 越权访问 **越权访问&#xff08;Authorization Bypass&#xff09;**是指&#xff1a;攻击者绕过了权限控制机制&#xff0c;访问或操作了非其权限范围内的资源或功能。 换句话说&#xff0c;系统该拦你没拦&#xff0c;你就越权成功了。 1.1.1 …

分布式缓存:ZSET → MGET 跨槽(cross‐slot)/ 并发 GET解决思路

文章目录 缓存全景图Pre问题描述解决思路一、管道&#xff08;Pipelining&#xff09;替代多线程二、使用 Hash Tag 保证数据同槽三、用 Hash 结构一次性批量取值四、把数据直接存进 ZSET&#xff08;或用 RedisJSON&#xff09; 小结 缓存全景图 Pre 分布式缓存&#xff1a;缓…

开发AR导航助手:ARKit+Unity+Mapbox全流程实战教程

引言 在增强现实技术飞速发展的今天&#xff0c;AR导航应用正逐步改变人们的出行方式。本文将手把手教你使用UnityARKitMapbox开发跨平台AR导航助手&#xff0c;实现从虚拟路径叠加到空间感知的完整技术闭环。通过本教程&#xff0c;你将掌握&#xff1a; AR空间映射与场景理…

助力 FPGA 国产化,ALINX 携多款方案亮相深圳、广州“紫光同创 FPGA 技术研讨会”

5 月中旬&#xff0c;一年一度的紫光同创技术研讨会系列活动正式拉开帷幕&#xff0c;相继在深圳、广州带来 FPGA 技术交流盛宴。 ALINX 作为紫光同创官方合作伙伴&#xff0c;长期助力推动 FPGA 国产化应用发展&#xff0c;此次携多款基于 Kosmo-2 系列产品开发的方案 demo 亮…

LeetCode 1040.移动石子直到连续II

在 X 轴上有一些不同位置的石子。给定一个整数数组 stones 表示石子的位置。 如果一个石子在最小或最大的位置&#xff0c;称其为 端点石子。每个回合&#xff0c;你可以将一颗 端点石子 拿起并移动到一个未占用的位置&#xff0c;使得该石子不再是一颗 端点石子。 值得注意的…

梯度优化提示词:精准引导AI分类

基于梯度优化的提示词工程方法,通过迭代调整提示词的嵌入向量,使其能够更有效地引导模型做出正确分类。 数据形式 训练数据 train_data 是一个列表,每个元素是一个字典,包含两个键: text: 需要分类的文本描述label: 对应的标签(“冲动"或"理性”)示例数据: …

JavaWeb:SpringBoot配置优先级详解

3种配置 打包插件 命令行 优先级 SpringBoot的配置优先级决定了不同配置源之间的覆盖关系&#xff0c;遵循高优先级配置覆盖低优先级的原则。以下是详细的优先级排序及配置方法说明&#xff1a; 一、配置优先级从高到低排序 1.命令行参数 优先级最高&#xff0c;通过keyvalu…