news 2026/4/23 11:31:32

【JavaSE】十六、文件IO File类 字节流 字符流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【JavaSE】十六、文件IO File类 字节流 字符流

文章目录

  • Ⅰ. 文件 `IO` 的常用核心类(来自 `java.io` 包)
  • Ⅱ. `File` 类
  • 题外话:try-with-resources⭐
  • Ⅲ. 字节流
    • 一、输入样例
    • 二、输出样例
  • Ⅳ. 字符流
    • 一、输入样例
    • 二、输出样例


Java IO分为两个主要家族:
  1. 传统IOjava.io包):基于流(Stream),数据一个字节(字符)一个字节(字符)地流动。适合较小数据量、阻塞式处理。
  2. NIONew IOjava.nio包):基于缓冲区(Buffer) 和 通道(Channel),更高效、支持非阻塞 IO(可用于高性能服务器),适合大规模并发处理。

这里主要介绍传统IO,对于文件操作来说也主要用到的是传统IO,而网络通信会用到NIO,并且现在主流的框架已经集成了NIO,所以不需要我们去调用NIO的原生API,所以这里不重点展开学,等到后面学框架的时候再学习时候使用即可!

Ⅰ. 文件IO的常用核心类(来自java.io包)

类名类型功能
File表示文件或目录,不进行读写——
FileInputStream / FileOutputStream字节流用于读写文件(低级)
BufferedInputStream / BufferedOutputStream字节缓冲流加快读写速度,包装在流外层
FileReader / FileWriter字符流用于读写文本文件,单字符读取(低效)
BufferedReader / BufferedWriter字符缓冲流高效读写文本文件,提供按行读取等功能
InputStreamReader / OutputStreamWriter转换流字节流与字符流之间的桥梁
ObjectInputStream / ObjectOutputStream对象流支持对象的序列化与反序列化

💥注意事项:

  1. 其实因为FileReaderFileWriter的局限性,比如不能指定编码、功能较弱、封装层少等,所以一般处理字符流的时候,用的是FileInputStreamFileOutputStream分别搭配上ScannerPrintWriter即可!
  2. Java IO使用装饰者模式Decorator),允许你用更强功能 “包裹” 基础流,如下所示:
// 字节流包裹BufferedInputStreamin=newBufferedInputStream(newFileInputStream("file.txt"));// 字符流包裹BufferedReaderbr=newBufferedReader(newFileReader("test.txt"))

Ⅱ.File

Filejava.io包中的一个核心类,用于表示文件或目录的抽象路径名,但它本身不进行文件内容读写,而是用于检查、创建、删除、重命名文件和目录等 “元数据” 操作。

方法 / 构造器返回类型说明
File(String pathname)构造器通过路径字符串构造文件或目录
File(String parent, String child)构造器使用父路径 + 子路径构造
File(File parent, String child)构造器使用父 File + 子路径构造
exists()boolean路径是否存在
isFile()boolean是否是普通文件
isDirectory()boolean是否是目录
createNewFile()boolean创建文件(已存在时不创建)
mkdir()boolean创建目录(单层)
mkdirs()boolean创建目录(多层)
delete()boolean删除文件或空目录
getName()String获取文件/目录名
getPath()String返回构造File对象时传入的路径(原样返回,可能是相对路径
getAbsolutePath()String获取绝对路径,但不解析符号链接或目录符号
getCanonicalPath()String获取绝对路径,解析符号链接、...,等价于真实路径
getParent()String获取父路径(字符串)
length()long获取文件大小(字节)
lastModified()long最后修改时间戳(毫秒)
renameTo(File dest)boolean重命名或移动文件
list()String[]返回目录下的文件名数组
listFiles()File[]返回目录下的 File 对象数组
canRead() / canWrite()boolean是否可读 / 可写
setReadOnly()boolean设置为只读
isHidden()boolean是否是隐藏文件

举个例子,假如当前路径是/home/user,然后代码如下所示:

File file=newFile("../test.txt");System.out.println("getPath(): "+file.getPath());System.out.println("getAbsolutePath(): "+file.getAbsolutePath());System.out.println("getCanonicalPath(): "+file.getCanonicalPath());// 结果:getPath():../test.txtgetAbsolutePath():/home/user/../test.txtgetCanonicalPath():/home/test.txt

题外话:try-with-resources⭐

try-with-resourcesJava 7引入的一种简洁语法结构,用于自动关闭实现了AutoCloseableCloseable接口的资源,主要是确保资源在使用完毕后被自动关闭,即使中间发生异常,也不会泄露资源

传统写法有点累赘,不优雅,如下所示:

try{BufferedReaderreader=newBufferedReader(newFileReader("file.txt"));Stringline=reader.readLine();System.out.println(line);}catch(IOExceptione){e.printStackTrace();}finally{if(reader!=null){try{reader.close();}catch(IOExceptionex){ex.printStackTrace();}}}

try-with-resources写法如下所示:

try(BufferedReaderreader=newBufferedReader(newFileReader("file.txt"))){Stringline=reader.readLine();System.out.println(line);}catch(IOExceptione){e.printStackTrace();}

优势:

  1. 更简洁
  2. 自动关闭资源(省去了finally块)
    1. try中声明的资源,编译器会自动生成finally代码块来调用它们的.close()方法。
  3. 避免资源泄漏
    1. 即使try里面发生异常,Java保证所有资源都被依次、倒序地关闭
    2. 如果close()方法本身也抛出异常,这些异常会被添加为抑制异常suppressed exceptions),而不会吞掉原来的主异常。
  4. try中可以有多个语句,需要;分割即可!

Ⅲ. 字节流

字节流主要用于处理二进制数据(如图片、音频、视频、文件),分别有输入字节流和输出字节流,但它们都是抽象类,需要通过特定功能的子类来创建实例,我们重点放在文件相关的字节流类上!

抽象类子类示例
InputStreamFileInputStream、BufferedInputStream、DataInputStream等等
OutputStreamFileOutputStream、BufferedOutputStream、DataOutputStream等等

下面是两者各自的方法以及共同的方法:

方法签名返回类型功能说明
🔹 FileInputStream 专属方法
int read()int读取单个字节(返回 0–255,返回 -1 表示 EOF)
int read(byte[] b)int读取多个字节,存入数组,返回实际读取的字节数
int read(byte[] b, int off, int len)int从偏移量 off 开始读取 len 个字节
int available()int返回可读取的字节数(非阻塞)
long skip(long n)long跳过 n 个字节,返回实际跳过的字节数
🔸FileOutputStream 专属方法
void write(int b)void写出一个字节(仅低 8 位有效)
void write(byte[] b)void写出整个字节数组
void write(byte[] b, int off, int len)void从偏移量off写出len个字节
void flush()void强制刷新缓冲区,将数据立即写入文件
🔁两者共有方法
void close()void关闭流并释放系统资源
FileDescriptor getFD()FileDescriptor获取底层文件描述符,用于底层文件操作(少用)

一、输入样例

publicstaticvoidmain(String[]args){// try-with-resources风格:try(InputStreamin=newFileInputStream("./main.txt")){byte[]buf=newbyte[1024];while(true){intn=in.read(buf);// 磁盘数据读取到buf中if(n==-1){System.out.println("读取完毕");break;}// 处理数据,比如输出数据for(inti=0;i<n;++i){System.out.printf("0x%x\n",buf[i]);// 十六进制输出}}}catch(IOExceptione){e.printStackTrace();}}

二、输出样例

publicstaticvoidmain(String[]args){try(OutputStream out=newFileOutputStream("./main1.txt")){byte[]buf={97,98,99,100};out.write(buf);// 将buf数据写入到文件中去}catch(IOException e){e.printStackTrace();}}

Ⅳ. 字符流

这里主要采用的还是文件字节流加上ScannerPrintWriter来处理字符,这两者分别有以下优势:

  1. Scanner可以轻松地读取int,double,String, 一行一行地处理文本(nextLine()nextInt()等),还可以设置编码格式!又因为它接受InputStream作为输入源,所以能直接配合FileInputStream使用!
  2. PrintWriter支持print(),println(),printf()等方法,并且支持write(String),即可以传入String参数,这种支持是非常爽的!

一、输入样例

publicstaticvoidmain(String[]args){try(InputStreamin=newFileInputStream("./main.txt");Scanner sc=newScanner(in,"UTF-8")){// 循环读入每一行,然后输出while(sc.hasNext()){String line=sc.nextLine();System.out.println(line);}}catch(IOException e){e.printStackTrace();}}

二、输出样例

publicstaticvoidmain(String[]args){try(OutputStream out=newFileOutputStream("./main2.txt","UTF-8");PrintWriter pw=newPrintWriter(out)){// 将文本输出到文件中,可以直接传String类型pw.write("啊啊~利刃啊liren\n利刃阿斯顿");}catch(IOException e){e.printStackTrace();}}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:26:52

9 个自考答辩PPT模板,AI降重工具推荐

9 个自考答辩PPT模板&#xff0c;AI降重工具推荐 论文写作的困局&#xff1a;时间紧、任务重、降重难 对于自考学生而言&#xff0c;毕业答辩不仅是对知识的总结&#xff0c;更是对个人能力的全面检验。然而&#xff0c;在这个过程中&#xff0c;论文写作和文献综述往往成为最令…

作者头像 李华
网站建设 2026/4/18 6:46:55

【每日算法】LeetCode 19. 删除链表的倒数第 N 个结点

对前端开发者而言&#xff0c;学习算法绝非为了“炫技”。它是你从“页面构建者”迈向“复杂系统设计者”的关键阶梯。它将你的编码能力从“实现功能”提升到“设计优雅、高效解决方案”的层面。从现在开始&#xff0c;每天投入一小段时间&#xff0c;结合前端场景去理解和练习…

作者头像 李华
网站建设 2026/4/20 14:34:03

Ubuntu命令行部署GPT-SoVITS语音合成指南

Ubuntu命令行部署GPT-SoVITS语音合成指南 在远程服务器上做语音合成&#xff0c;最头疼的莫过于没有图形界面——WebUI再炫酷也用不了。这时候&#xff0c;纯命令行就成了唯一的出路。本文记录的就是这样一个实战流程&#xff1a;如何在无GUI的Ubuntu环境中&#xff0c;从零开…

作者头像 李华
网站建设 2026/4/20 15:17:11

LobeChat能否设置额度预警?避免超额支出

LobeChat 能否设置额度预警&#xff1f;避免超额支出 在企业与个人纷纷拥抱大语言模型&#xff08;LLM&#xff09;的今天&#xff0c;AI聊天界面已成为人机交互的核心入口。然而&#xff0c;随着调用量的增长&#xff0c;OpenAI 等云服务按 Token 计费的模式也带来了不可忽视的…

作者头像 李华
网站建设 2026/4/23 11:27:08

LobeChat能否用来练习外语口语?语音输入体验

LobeChat能否用来练习外语口语&#xff1f;语音输入体验 在如今这个语言学习资源触手可及的时代&#xff0c;很多人依然卡在一个最基础的问题上&#xff1a;敢不敢开口说。教材背得滚瓜烂熟&#xff0c;语法掌握得头头是道&#xff0c;可一到真实对话场景就大脑空白、结结巴巴。…

作者头像 李华