Java的IO流
1、流的是什么
流就是一连串的连续动态数据的集合,在Java的IO流中我们可以将其看做一个管道,将其包含输入输出流,Sourcet通过输入流将数据信息传给程序,而程序又通过输出流将数据信息传给目的地。就类似于我们从外部将东西传给程序就要输入流,我们从程序传给外部就要输出流。
2、四大IO抽象类
我们可以通过字节流和字符流来区分这四大IO抽象流。
字节流分为 InputStream 和 OutputStream :操作数据单位以字节 byte 为基础单位
字符流分为 Reader 和 Writer : 负责输出、写入数据,操作单位以字符 char 为基础单位
这里有疑问了,为什么有了字节流读取数据还要字符流这种方式呢:
由于存在不同的编码方式,不同编码方式字符对应不同的字节(如Java字符是采用 Unicode编码,一个英文为1byte,一个中文对应2byte,而在UTF-8编码中,一个英文为1byte,一个中文为3byte),因此为了方便处理如文中文这类字符数据时,会更优先考虑使用字符流。所以这也是Java针对不同情况进行考虑从而设计的结果。所以一般操作文件(如copy file ,music,video这种二进制文件),会考虑使用字节流。而操作文本、字符串(如读取、写入中文字符串),会考虑使用字符流。
3、关于字节输入流与字节输出流 InputStream 、 OutputStream
3.1字节输入流 InputStream
InputStream是所有输入字节流的父类,常用到的三个不同输入参数的读取方法:
- int read():读取一个字节数据,并返回读到的数据,如果返回-1,表示已经读到了数据流的末尾
- int read(byte[] b):将数据读入一个字节数组,同时返回实际读取的字节数,如果返回-1表示已经读到了输入流的末尾
- int read(byte[] b, int off, int len):将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾,off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。
- read() 方法有一个共同点,就是当读取到末尾则会返回-1,表示已经读取完毕。
关于InputStream,用的最多的是FileInputStream、BufferedInputStream。
- FileInputStream 是文件字节输入流,一般操作文件(copy file ,music,video这种二进制文件),会考虑使用FileInputStream字节流
- BufferedInputStream 内部实现了一个缓冲区数组,可以一次性读取defaultBufferSize个字节,先缓存至数组(默认defaultBufferSize = 8192),BufferedInputStream 读文件性能高于 FileInputStream
3.2字节输出流 - OutputStream
OutputStream 是对应InputStream 的输出流,是所有输出字节流的父类
- write(int b):往输出流中写入一个字节
- write(byte[] b):往输出流中写入数组b中的所有字节
- write(byte[] b, int off, int len):往输出流中写入数组b中从偏移量中off开始的len个字节的数据
- flush():刷新输出流,强制缓存区中的输出字节被写入(写入时要记得刷新一下,不然可能存在于缓冲区位写入)
- close():关闭输出流,释放和这个流相关的系统资源
和OutputStream一样,用的较多的是FileInputStream、BufferedOutputStream
4、关于字符输出流与字节输出流-Reader、Writer
4.1字符输入流 Reader
Reader 是所有字符流的父类,是一个抽象类,与上面的字节流是一样的,不同的是它是以字符为单位读取,他有三个不同输入参数的读方法:
- int read():读物一个字符,返回值为读取的字符。
- int read(char cbuf[]):读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量
- int read(char cbuf[], int off, int len):读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现
关于Reader,用的最多的是BufferedReader、InputStreamReader
- InputStreamReader 将字节流转变为字符流,作为连接字节流和字符流的桥梁
- BufferedReader 加了缓存数组的方法,提高了性能。
4.2字符输出流 writer
Reader是所有输出字符流的父类,是一个抽象类,有5个不同输入残水的写法:
- write(int c):写入单子字符
- write(char cbuf[]):将字符数组cbuf[]写到输出流
- write(char cbuf[], int off, int len):将字符数组cbuf[]中从索引为off的位置处开始的len个字符写入输出流
- write(string str):将字符串str中的字符写入输出流
- write(string str, int off, int len):建字符串str中从索引off开始处的len个字符写入输出流
关于writer,用的最多的是bufferwriter、OutputStreamwriter
- OutputStreamWriter 将字节流转变为字符流是OutputStream 到write转换的桥梁
- BufferedWriter 加了缓冲数组方法,提高了写性能。
5、具体使用
public static void main(String[] args) throws IOException { FileInputStream fileInputStream = null; int readLength = 0; byte[] bytes = new byte[1024]; try { fileInputStream = new FileInputStream("文件地址"); while ((readLength = fileInputStream.read(bytes)) != -1) { System.out.println(new String(bytes,0,readLength)); } } catch (IOException e) { System.out.println(); } finally { fileInputStream.close(); } }
使用 FileOutputStream 在 hello.txt 文件中写入 “hello,world”,如果文件不存在,会创建文件(前提是文件存在)
public static void main(String[] args) throws IOException { File file = new File("文件地址"); if (!file.exists()) { file.createNewFile(); } //这里构造器如果加true,表示追加模式,如果不写,默认是覆盖原来的内容 FileOutputStream fileOutputStream = new FileOutputStream(file, true); try { byte[] bytes = "hello world".getBytes(); fileOutputStream.write(bytes); } finally { fileOutputStream.close(); } }
图片文件的拷贝
public static void main(String[] args) throws IOException { FileInputStream fileInputStream = new FileInputStream("源文件地址"); FileOutputStream fileOutputStream = new FileOutputStream("目标文件地址"); int readLen = 0; byte[] bytes = new byte[1024]; try { while ((readLen = fileInputStream.read(bytes)) != -1) { fileOutputStream.write(bytes,0,readLen); } } finally { fileInputStream.close(); fileOutputStream.close(); } }
public static void main(String[] args) throws IOException { FileReader fileReader = new FileReader("文件路径"); int readLen = 0; char[] chars = new char[1024]; try { while ((readLen = fileReader.read(chars )) != -1) { System.out.println(new String(chars,0,readLen)); } } finally { fileReader.close(); } }
5.4
public static void main(String[] args) throws IOException { FileWriter fileWriter = new FileWriter("文件路径/note.txt", true); try { fileWriter.write("风雨之后,定见彩虹"); } finally { fileWriter.close(); } }
5.5BufferReader(包装流,字符流)
使用BufferReader读取文件,并打印到控制台
public static void main(String[] args) throws IOException { BufferedReader bufferedReader = new BufferedReader(new FileReader("文件路径")); String readLen; try { while ((readLen = bufferedReader.readLine()) != null) { System.out.println(readLen;); } } catch (IOException e) { throw new RuntimeException(e); } finally { bufferedReader.close(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南