当前位置: 首页 > 技术教程

Java文件读写怎么操作? 字节流和字符流有啥不同?

  文件读写是Java程序与外部存储交互的核心功能,用于实现数据的持久化(如保存用户配置、记录日志、读取数据文件等)。Java 通过流”(Stream)机制处理文件读写,流是数据传输的抽象,按处理数据的类型可分为字节流和字符流。掌握这两种流的使用方法及区别,是实现高效文件操作的基础。

  一、Java 文件读写的基本操作

  (一)字节流:处理所有类型文件

  字节流以字节(8 位二进制)为单位处理数据,可读写任意类型文件(如文本、图片、视频等),核心类包括FileInputStream(字节输入流)和FileOutputStream(字节输出流)。

  字节流读文件(输入流)

  步骤:创建FileInputStream对象 → 读取字节 → 关闭流(释放资源)。

  示例:读取文本文件内容

  import java.io.FileInputStream;import java.io.IOException;public class ByteStreamRead { public static void main(String[] args) { try (FileInputStream fis = new FileInputStream("test.txt")) { // try-with-resources自动关闭流 byte[] buffer = new byte[1024]; // 缓冲区,一次读取1024字节 int len; while ((len = fis.read(buffer)) != -1) { // 读取到末尾返回-1 System.out.print(new String(buffer, 0, len)); // 转换为字符串输出 } } catch (IOException e) { e.printStackTrace(); } }}

  字节流写文件(输出流)

  步骤:创建FileOutputStream对象 → 写入字节 → 关闭流。

  示例:向文件写入内容

  import java.io.FileOutputStream;import java.io.IOException;public class ByteStreamWrite { public static void main(String[] args) { try (FileOutputStream fos = new FileOutputStream("output.txt")) { String content = "Hello, 字节流!"; fos.write(content.getBytes()); // 将字符串转为字节数组写入 fos.flush(); // 刷新缓冲区,确保数据写入文件 } catch (IOException e) { e.printStackTrace(); } }}

  (二)字符流:处理文本文件

  字符流以字符(通常为 16 位 Unicode)为单位处理数据,专为文本文件(如.txt、.java)设计,能自动处理字符编码(如 UTF-8、GBK),核心类包括FileReader(字符输入流)和FileWriter(字符输出流)。

  字符流读文件

  示例:读取文本文件(自动处理编码)

  import java.io.FileReader;import java.io.IOException;public class CharStreamRead { public static void main(String[] args) { try (FileReader fr = new FileReader("test.txt")) { char[] buffer = new char[1024]; // 字符缓冲区 int len; while ((len = fr.read(buffer)) != -1) { System.out.print(new String(buffer, 0, len)); } } catch (IOException e) { e.printStackTrace(); } }}

  字符流写文件

  示例:向文本文件写入内容

  import java.io.FileWriter;import java.io.IOException;public class CharStreamWrite { public static void main(String[] args) { try (FileWriter fw = new FileWriter("output.txt")) { String content = "Hello, 字符流!"; fw.write(content); // 直接写入字符串 fw.flush(); } catch (IOException e) { e.printStackTrace(); } }}

  (三)缓冲流:提升读写效率

  缓冲流(BufferedInputStream/BufferedOutputStream、BufferedReader/BufferedWriter)通过缓冲区减少磁盘 IO 次数,大幅提升读写效率,建议优先使用。

  示例:缓冲字符流读文件

  import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;public class BufferedRead { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { String line; while ((line = br.readLine()) != null) { // 按行读取,效率更高 System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } }}

360截图20250425224758032.jpg

  二、字节流与字符流的核心区别

  对比维度字节流(Byte Stream)字符流(Character Stream)

  处理数据单位字节(8 位)字符(16 位 Unicode,与编码相关)

  适用文件类型所有类型(文本、图片、视频等)仅文本文件(如.txt、.java)

  编码处理不处理编码,直接操作原始字节自动处理编码,将字节转为字符(需匹配文件编码)

  核心类FileInputStream、FileOutputStreamFileReader、FileWriter

  特有功能无(通用处理)支持按行读写(如BufferedReader.readLine())

  (一)数据处理方式的本质差异

  字节流是 “底层流”,直接操作二进制数据,不关心数据含义,因此可处理任何文件;字符流是 “高层流”,基于字节流实现,会根据编码规则(如 UTF-8)将字节转换为字符,仅适用于文本文件。若用字符流处理图片、视频等二进制文件,会因编码转换破坏原始数据。

  (二)编码问题的影响

  字符流读写时需保证流的编码与文件实际编码一致,否则会出现乱码。例如,用FileReader读取 UTF-8 编码的文件时,若系统默认编码为 GBK,可能出现乱码(需通过InputStreamReader指定编码);而字节流读取文本文件时,需手动指定编码(如new String(buffer, "UTF-8")),更灵活但易出错。

  三、文件读写的注意事项

  资源释放:流操作会占用系统资源,必须关闭(推荐使用try-with-resources语法自动关闭,JDK 7 + 支持)。

  路径处理:文件路径需准确,相对路径基于程序运行目录,绝对路径从根目录开始(如C:/data/test.txt)。

  异常处理:文件读写可能抛出IOException(如文件不存在、权限不足),必须捕获或声明抛出。

  大文件处理:读写大文件时需使用缓冲区(如byte[]、char[]),避免一次性加载到内存导致溢出。

  字节流和字符流的选择需根据文件类型:处理图片、视频等二进制文件用字节流;处理文本文件优先用字符流(简化编码处理)。实际开发中,缓冲流因效率优势应作为首选,结合try-with-resources语法可写出简洁、安全的文件操作代码。掌握这两种流的特性,能应对绝大多数 Java 文件读写场景。

 


猜你喜欢