文章目录
IO流
1.IO流的介绍
- I表示intput,把硬盘文件中的数据读入到内存的过程,称之输入,负责读;
- O表示output,把内存中的数据写出到硬盘文件的过程,称之输出,负责写。
2.IO流的分类
3.IO流体系
Java 提供了专用于输入输出功能的包java.io
- 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流称为字节输入流。
- 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流称为字节输出流。
- 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流称为字符输入流。
- 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流称为字符输出流
File类
(在IO流之前,首先介绍一下Java中的文件File类)
1.介绍
File:它是文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的;
- File类的对象代表操作系统的文件,File封装了对文件进行:删除、获取信息、创建文件或文件夹等操作。但是 不能读写文件内容;
- 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已(可以存在或不存在)将来是要通过具体的操作把这个路径的内容转换为具体存在的。
2.构造方法
方法 | 含义 |
---|---|
File(String pathname) | 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例 |
File(File parent, String child) | 从父抽象路径名和子路径名字符串创建新的File实例 |
File(String parent, String child) | 从父路径名字符串和子路径名字符串创建新的File实例 |
总之,比较常用的就是通过绝对路径和相对路径来访问文件
// 绝对路径
File file = new File("D:\\1.jpeg");
long size = file.length(); // 输出的是字节大小
System.out.println(size);
// 相对路径
File f = new File("src/io/file/1.jpeg");
System.out.println(f.length());
3.常用方法
(1)判断文件类型、获取文件信息功能:
(2)创建文件的功能:
字节流
两个抽象基类
- lnputStream:字节输入流的所有类的超类
- OutputStream:字节输出流的所有类的超类
子类名特点:子类名称都是以其父类名作为子类名的后缀
字节流的类层次图如下:

常用的主要是:FileOutputStream,BufferedOutputStream,FileInputStream,BufferedInputStream
1.字节输入流(读数据)
读数据采用的是FileInputStream
类(从文件系统中的文件获取输入字节)
FilelnputStream(String name):通过打开与实际文件的连接来创建一个FilelnputStream,该文件由文件系统中的路径名name命名
使用字节输入流读数据的步骤:
- 创建字节输入流对象;
- 调用字节输入流对象的读数据方法;
- 释放资源
读数据方法:(一个字节&一个字节数组)
方法 | 含义 |
---|---|
int read() | 每次读取一个字节并返回,没有可读返回-1 |
int read(byte[] buffer) | 每次读取一个字节数组返回读取个数,没有可读返回-1 |
FileInputStream fs = new FileInputStream("src/io/1.txt");
// 一次读一个字节
int b;
while((b=fs.read())!=-1)
System.out.print((char)b+" ");
// 一次读一个字节数组
int len;
byte[] buffer =new byte[3];
while((len = fs.read(buffer))!=-1)
System.out.print(new String(buffer,0,len));
读取文件的全部字节:
byte[] buffer = fs.readAllBytes();
System.out.println(new String(buffer));
2.字节输出流(写数据)
采用字节流的具体实现子类FileOutputStream
——文件输出流用于将数据写入磁盘
FileOutputStream构造方法:
构造方法 | 含义 |
---|---|
FileOutputStream(String name) | 创建文件输出流以指定的名称写入文件 |
FileOutputStream(String name, boolean append) | 创建文件输出流以指定的名称写入文件,可追加数据 |
FileOutputStream(File file) | 创建文件输出流以写入由指定的 File对象表示的文件 |
FileOutputStream(File file,boolean append) | 创建文件输出流以写入由指定的 File对象表示的文件,可追加数据 |
写入数据的步骤:
- 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
- 调用字节输出流对象的写数据方法
- 释放资源(关闭此文件输出流并释放与此流相关联的任何系统资源)
字节流写数据的三种方法:
方法 | 含义 |
---|---|
void write(int b) | 将指定的字节写入此文件输出流,一次写一个字节数据 |
void write(byte[ ] b) | 将b.length字节从指定的字节数组写入此文件输出流,一次写一个字节数组数据 |
void write(byte[ ] b, int off, int len) | 将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流,一次写一个字节数组的部分数据 |
代码演示:
FileOutputStream fos = new FileOutputStream("1.txt");
fos.write("Test java FileOutputStream!".getBytes());
fos.close();
// 1.创建输出流对象
OutputStream os = new FileOutputStream("out.txt" , true); // 追加数据管道
//OutputStream os = new FileOutputStream("out1.txt"); // 先清空之前的数据,写新数据进入
// 2、写数据出去
// a.public void write(int a):写一个字节出去
os.write('a');
os.write(98);
os.write("\r\n".getBytes()); // 换行
// b.public void write(byte[] buffer):写一个字节数组出去。
byte[] buffer = {'a' , 97, 98, 99};
os.write(buffer);
os.write("\r\n".getBytes()); // 换行
byte[] buffer2 = "国庆快乐".getBytes();
os.write(buffer2);
os.write("\r\n".getBytes()); // 换行
//os.flush(); // 写数据必须,刷新数据 可以继续使用流
os.close(); // 释放资源,包含了刷新的!关闭后流不可以使用了
字符流
字符流体系结构:
为什么会出现字符流?
由于字节流操作中文不是特别的方便,所以Java就提供字符流
即 字符流=字节流+编码表
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
1.字符输入流(读数据)
字符输入流采用的是实现类FileReader
类
构造器:
构造方法 | 含义 |
---|---|
FileReader(File file) | 创建字符输入流管道与源文件对象接通 |
FileReader(String pathname) | 创建字符输入流管道与源文件路径接通 |
字符读取方法:
方法 | 含义 |
---|---|
int read() | 每次读取一个字符返回,如果字符已经没有可读的返回-1 |
int read(char[] buffer) | 每次读取一个字符数组,返回读取的字符个数,如果字符已经没有可读的返回-1 |
代码示例:
// 1、创建一个字符输入流管道与源文件接通
Reader fr = new FileReader("1.txt");
// 2、使用循环每次读取一个字符
int code;
while ((code = fr.read()) != -1) {
System.out.print((char) code);
// 3.用字符数组
char[] buffer = new char[1024]; // 1K字符
int len;
while ((len = fr.read(buffer)) != -1) {
String rs = new String(buffer, 0, len);
System.out.print(rs);
}
1.字符输出流(写数据)
字符输入流采用的是实现类FileWriter
类
构造器:
写字符方法:
方法 | 含义 |
---|---|
void write(int c) | 写入一个字符 |
void write(char[] cbuf) | 写入一个字符数组 |
void write(char[]cbuf, int off, int len) | 写入字符数组的一部分 |
void write(String str) | 写一个字符串 |
void write(String str int off, int len) | 写一个字符串的一部分 |
// 1、创建一个字符输出流管道与目标文件接通
// Writer fw = new FileWriter("file-io-app/src/out08.txt"); // 覆盖管道,每次启动都会清空文件之前的数据
Writer fw = new FileWriter("3.txt", true); // 覆盖管道,每次启动都会清空文件之前的数据
// a.public void write(int c):写一个字符出去
fw.write(98);
fw.write('a');
fw.write('徐'); // 可以直接写中文了
fw.write("\r\n"); // 换行
// b.public void write(String c)写一个字符串出去
fw.write("abc我是中国人");
fw.write("\r\n"); // 换行
// c.public void write(char[] buffer):写一个字符数组出去
char[] chars = "abc我是中国人".toCharArray();
fw.write(chars);
fw.write("\r\n"); // 换行
// fw.flush();// 刷新后流可以继续使用
fw.close(); // 关闭包含刷线,关闭后流不能使用
缓冲流
缓冲流也称为高效流、或者高级流。之前的字节流可以称为原始流。
作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能。
字节缓冲流为什么提高了操作数据的性能?
- 字节缓冲流自带8KB缓冲区
- 可以提高原始字节流、字符流读写数据的性能
1.字节缓冲流
构造器 | 含义 |
---|---|
BufferedOutputStream(OutputStream out) | 可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能 |
BufferedInputStream(InputStream in) | 可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能 |
为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作。
2.字符缓冲流
构造器 | 含义 |
---|---|
BufferedWriter(Writer out) | 将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小 |
BufferedReader(Reader in) | 从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以读取缓冲区大小,或者可以使用默认大小 |