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

黑马JAVA+AI 加强09-2 IO流-文件字节输入流-文件字节输出流-文件字符流-文件字符输出流

1.输入流-输出流
在这里插入图片描述
1.1文件字节输入流-适合文件复制
在这里插入图片描述
在这里插入图片描述
1.2 代码案例

public class FileInputStreamDemo2 {public static void main(String[] args) throws Exception {// 目标:掌握文件字节输入流读取文件中的字节数组到内存中来。// 1、创建文件字节输入流管道于源文件接通InputStream is = new FileInputStream("day03-file-io\\src\\dlei02.txt"); // 2、开始读取文件中的字节并输出: 每次读取一个字节// 定义一个变量记住每次读取的一个字节int b;while ((b = is.read()) != -1) {System.out.print((char) b);}1.性能问题:每次只读取 1 个字节,需要频繁与磁盘交互,对于大文件来说效率极低。2.乱码问题:字节流读取汉字时一定会乱码。因为汉字在 UTF-8、GBK 等编码中通常占用 2-3 个字节,而read()每次只读取 1 个字节,无法完整解析汉字的编码,导致输出乱码。}
}

改进方向 1:使用字节数组批量读取(提升性能,但仍可能乱码)

  • 通过定义字节数组作为缓冲区,一次读取多个字节,减少 IO 交互次数,提升性能。
public class FileInputStreamImproved1 {public static void main(String[] args) throws Exception {// 1. 创建文件字节输入流,连接目标文件InputStream is = new FileInputStream("day03-file-io\\src\\dlei02.txt");// 2. 定义字节数组作为缓冲区(长度建议为1024的倍数,如1024、2048等)byte[] buffer = new byte[1024];// 记录每次读取的有效字节数(避免读取到缓冲区中残留的旧数据)int len;// 3. 循环读取:每次读取最多buffer.length个字节,存入buffer,返回实际读取的字节数while ((len = is.read(buffer)) != -1) {// 将字节数组转换为字符串(需指定编码,否则使用系统默认编码,仍可能乱码)System.out.print(new String(buffer, 0, len, "UTF-8"));}// 4. 关闭流(释放资源,实际开发中建议用try-with-resources自动关闭)is.close();但字节流本身不处理编码,读取中文仍可能乱码(适合读取二进制文件,如图片、视频等)。}
}

在这里插入图片描述
1.3一次性读完,可以避免中文乱码,但也不是什么好办法
在这里插入图片描述
2.文件字节输出流
在这里插入图片描述
2.1 文件字节输出流构造器和方法
在这里插入图片描述
案例 1:基本使用(覆盖写入单个字节 / 字节数组)

public class FileOutputStreamDemo1 {public static void main(String[] args) throws Exception {// 1. 创建输出流管道(文件不存在会自动创建;存在则覆盖原内容)OutputStream os = new FileOutputStream("output1.txt");// 2. 写入数据// 方式1:写单个字节(只取int的低8位作为字节)os.write(97); // 写入'a'(ASCII码97)os.write(10); // 写入换行符'\n'// 方式2:写字节数组(适合批量写入,效率高)byte[] data = "Hello, FileOutputStream!".getBytes(); // 字符串转字节数组(默认编码)os.write(data);// 3. 关闭流(释放资源,必须执行)os.close();System.out.println("写入完成!");}
}

案例 2:追加写入(不覆盖原有内容)

public class FileOutputStreamDemo2 {public static void main(String[] args) throws Exception {// 1. 创建输出流管道(第二个参数为true表示追加模式)OutputStream os = new FileOutputStream("output2.txt", true);// 2. 追加写入数据byte[] appendData = "\n这是追加的内容!".getBytes("UTF-8"); // 指定编码避免中文乱码os.write(appendData);// 3. 关闭流os.close();System.out.println("追加写入完成!");}
}

案例 3:写入字节数组的一部分

public class FileOutputStreamDemo3 {public static void main(String[] args) throws Exception {OutputStream os = new FileOutputStream("output3.txt");byte[] data = "abcdefghijk".getBytes();// 写入数组从索引2开始,长度为4的部分(即"cdef")os.write(data, 2, 4);os.close();System.out.println("部分写入完成!");}
}

案例 4:结合 try-with-resources 自动关闭流(推荐)

public class FileOutputStreamDemo4 {public static void main(String[] args) {// try-with-resources:流会自动关闭,无需手动调用close()try (OutputStream os = new FileOutputStream("output4.txt")) {String content = "使用try-with-resources更安全!\n中文也能正常写入~";os.write(content.getBytes("UTF-8")); // 显式指定编码,避免中文乱码System.out.println("自动关闭流模式写入完成!");} catch (Exception e) {e.printStackTrace();}}
}

2.2 文件复制案例
在这里插入图片描述

  • 以下是基于字节流实现文件复制的代码,通过FileInputStream读取源文件字节,再用FileOutputStream写入目标文件,适用于任何类型的文件(图片、文档、视频等):

代码1:不推荐-太臃肿
在这里插入图片描述

public class FileCopyDemo {public static void main(String[] args) {// 源文件路径(需要复制的文件)String sourcePath = "D:\\original.jpg";// 目标文件路径(复制后的文件)String targetPath = "C:\\copy.jpg";// 定义输入流、输出流变量InputStream is = null;OutputStream os = null;try {// 1. 创建字节输入流(连接源文件)和字节输出流(连接目标文件)is = new FileInputStream(sourcePath);os = new FileOutputStream(targetPath);// 2. 定义字节数组作为缓冲区(提升复制效率,建议1024的倍数)byte[] buffer = new byte[1024 * 8]; // 8KB缓冲区int len; // 记录每次读取的有效字节数// 3. 循环读取源文件字节,并写入目标文件// 每次读取buffer长度的字节,存入buffer,返回实际读取的字节数(-1表示读取完毕)while ((len = is.read(buffer)) != -1) {// 将缓冲区中的字节写入目标文件(只写有效长度的字节)os.write(buffer, 0, len);}System.out.println("文件复制成功!");} catch (Exception e) {e.printStackTrace();} finally {// 4. 关闭流(先关输出流,再关输入流,避免资源泄漏)try {if (os != null) os.close();if (is != null) is.close();} catch (Exception e) {e.printStackTrace();}}}
}

代码2:推荐 简化版本(try-with-resources 自动关流):
在这里插入图片描述

public class FileCopySimple {public static void main(String[] args) {String sourcePath = "D:\\original.jpg";String targetPath = "C:\\copy.jpg";// try-with-resources自动关闭流(无需手动调用close())try (InputStream is = new FileInputStream(sourcePath);OutputStream os = new FileOutputStream(targetPath)) {byte[] buffer = new byte[1024 * 8];int len;while ((len = is.read(buffer)) != -1) {os.write(buffer, 0, len);}System.out.println("文件复制成功!");} catch (Exception e) {e.printStackTrace();}}
}

在这里插入图片描述
3.文件字符输入流-适合文本
在这里插入图片描述
在这里插入图片描述
3.1文件字符输入流构造器和方法
在这里插入图片描述

  • 以下是使用FileReader(文件字符输入流)读取文本文件的案例代码,展示了不同读取方式的用法(适合读取文本文件,能避免中文乱码):

案例 1:单个字符读取

public class FileReaderDemo1 {public static void main(String[] args) throws Exception {// 1. 创建字符输入流管道,连接源文件(文本文件路径)Reader fr = new FileReader("src/test.txt");// 2. 读取数据:每次读取一个字符int c; // 存储读取到的字符(ASCII码或Unicode码)while ((c = fr.read()) != -1) { // -1表示读取到文件末尾System.out.print((char) c); // 转换为字符并输出}// 3. 关闭流fr.close();}说明:read()方法每次读取一个字符(包括中文,因为字符流会自动处理编码),返回字符的 Unicode 值,转换为char即可正常显示。
}

案例 2:字符数组批量读取

public class FileReaderDemo2 {public static void main(String[] args) {Reader fr = null;try {// 1. 连接源文件fr = new FileReader("src/test.txt");// 2. 定义字符数组作为缓冲区(批量读取,减少IO次数)char[] buffer = new char[1024]; // 每次最多读1024个字符int len; // 记录每次实际读取的字符数// 3. 循环读取while ((len = fr.read(buffer)) != -1) {// 将字符数组的有效部分转换为字符串输出(0到len-1)System.out.print(new String(buffer, 0, len));}} catch (Exception e) {e.printStackTrace();} finally {// 4. 关闭流(确保资源释放)try {if (fr != null) fr.close();} catch (Exception e) {e.printStackTrace();}}}
}
说明:通过字符数组buffer批量读取,len记录实际读取的字符数,
避免读取到数组中残留的旧数据,效率远高于单个字符读取。

案例 3:结合 try-with-resources 自动关闭流(推荐,简化写法)

public class FileReaderDemo3 {public static void main(String[] args) {// try-with-resources:流会自动关闭,无需手动调用close()try (Reader fr = new FileReader("src/test.txt")) {char[] buffer = new char[512];int len;while ((len = fr.read(buffer)) != -1) {System.out.print(new String(buffer, 0, len));}} catch (Exception e) {e.printStackTrace();}}
}

在这里插入图片描述

在这里插入图片描述
3.2 文件字符输出流

  • 文件字符输入流构造器和方法
    在这里插入图片描述
  • 以下是使用FileWriter(文件字符输出流)写入文本文件的案例代码,覆盖不同写入方式和场景(适合处理文本内容,支持中文正常写入):

案例 1:基本写入(覆盖模式)

public class FileWriterDemo1 {public static void main(String[] args) throws Exception {// 1. 创建字符输出流管道(文件不存在会自动创建;存在则覆盖原内容)Writer fw = new FileWriter("output.txt");// 2. 写入数据// 方式1:写单个字符(int参数表示字符的Unicode值)fw.write('A'); // 写入字符'A'fw.write(97);  // 写入字符'a'(ASCII码97)fw.write('\n'); // 写入换行符// 方式2:写字符串(最常用,直接写入完整字符串)fw.write("Hello, FileWriter!\n");fw.write("中文写入也没问题~\n");// 方式3:写字符数组char[] chars = {'J', 'a', 'v', 'a', '!', '\n'};fw.write(chars);// 方式4:写字符串的一部分(从索引2开始,写5个字符)fw.write("abcdefghij", 2, 5); // 写入"cdefg"// 3. 关闭流(会自动刷新缓冲区,确保数据写入文件)fw.close();System.out.println("写入完成!");}
}

案例 2:追加写入(不覆盖原内容)

import java.io.FileWriter;
import java.io.Writer;public class FileWriterDemo2 {public static void main(String[] args) {Writer fw = null;try {// 1. 创建输出流(第二个参数为true表示追加模式)fw = new FileWriter("output.txt", true);// 2. 追加写入内容fw.write("\n--- 这是追加的内容 --- \n");fw.write("追加模式下,新内容会加在文件末尾~\n");} catch (Exception e) {e.printStackTrace();} finally {// 3. 关闭流(释放资源)try {if (fw != null) fw.close();} catch (Exception e) {e.printStackTrace();}}}
}

案例 3:使用 try-with-resources 自动关流(推荐)

public class FileWriterDemo3 {public static void main(String[] args) {// try-with-resources:流会自动关闭,无需手动调用close()try (Writer fw = new FileWriter("output.txt", true)) {// 写入字符数组的一部分(从索引1开始,写3个字符)char[] data = {'春', '夏', '秋', '冬'};fw.write(data, 1, 3); // 写入"夏秋"fw.write("\n使用try-with-resources更安全!\n");} catch (Exception e) {e.printStackTrace();}无需手动关闭流,代码更简洁,且能确保资源释放,适合实际开发。}
}

在这里插入图片描述
注意
在这里插入图片描述

  • 关键注意事项,核心是说明字符输出流在写入数据后,必须通过刷新(flush())或关闭(close())操作,才能让数据真正写入文件。

关键内容解释

  • 核心规则:字符输出流写出数据后,数据会先存到内存的缓冲区中,不会立即写入文件。必须执行flush()刷新流,或执行close()关闭流,才能将缓冲区的数据强制写入文件,使数据生效。
	FileWriter fw = new FileWriter("test.txt");fw.write("Hello");fw.flush(); // 数据立即写入文件,文件中已有“Hello”// 或执行 close()fw.close(); // 关闭时自动刷新,数据也会写入文件
http://www.dtcms.com/a/554193.html

相关文章:

  • Parasoft C/C++test如何在ARM DS-5环境中进行测试(下)
  • 佛山销售型网站建设重庆网红
  • Linux基础 -- 零拷贝之 splice
  • Go 协程
  • 做网站时怎样图片上传怎么才能让图片不变形有什么插件吗淄博住房和城乡建设局网站
  • leetcode1312.让字符串成为回文串的最少插入次数
  • 宜春做网站 黑酷seo快递网站建站需要什么
  • org.apache.commons.lang3都有什么常用的类
  • edas会议投稿显示格式错误+消除浮动块下面的空白
  • 宁波建设网站公司北京seo案例
  • 虚拟网站仿制教程河南国控建设集团招标网站
  • viewerjs+vue3 using typescript
  • U81904 【模板】树的直径
  • 如何将React自定义语法转化为标准JavaScript语法?
  • 自己做网站主机wordpress 引号被转义
  • 做营销网站推广快速开发安卓app
  • 文件基础操作详解
  • 【22】C语言 - 二维数组详解
  • 嵌入式项目代码架构与分层笔记
  • 自己房子做民宿挂什么网站数字今天科技 网站
  • 建设ca网站aws wordpress 集群
  • Rust数据类型(上):标量类型全解析
  • BPC EPM表单常规设置
  • 关于C++递归函数和指针部分
  • 基于STM32的智能天气时钟
  • 传奇网站建设网站开发公用头部
  • 安徽省建设厅官方网站黄世山电商办公室
  • 做的网站上更改内容改怎么办科技公司logo设计图片
  • 飞腾D2000/8在Ubuntu20.04下压力测试
  • 深度学习模型部署:将 TensorFlow 模型转为 TFLite 适配移动端