(在IO流之前,首先介绍一下Java中的文件File类)
File:它是文件和目录路径名的抽象表示
方法 | 含义 |
---|---|
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());
(1)判断文件类型、获取文件信息功能:
(2)创建文件的功能:
两个抽象基类
子类名特点:子类名称都是以其父类名作为子类名的后缀
字节流的类层次图如下:
常用的主要是:FileOutputStream,BufferedOutputStream,FileInputStream,BufferedInputStream
读数据采用的是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));
采用字节流的具体实现子类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就提供字符流
即 字符流=字节流+编码表
用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
字符输入流采用的是实现类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);
}
字符输入流采用的是实现类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(); // 关闭包含刷线,关闭后流不能使用
缓冲流也称为高效流、或者高级流。之前的字节流可以称为原始流。
作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能。
字节缓冲流为什么提高了操作数据的性能?
构造器 | 含义 |
---|---|
BufferedOutputStream(OutputStream out) | 可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能 |
BufferedInputStream(InputStream in) | 可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能 |
为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作。
构造器 | 含义 |
---|---|
BufferedWriter(Writer out) | 将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小 |
BufferedReader(Reader in) | 从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以读取缓冲区大小,或者可以使用默认大小 |