文章目录
IO流体系结构图解
- IO流的分类
- 按流的方向进行分类—含继承关系,如图:
- 按流中数据的最小单位
- 按流的方向进行分类—含继承关系,如图:
一、File类概述
1.1 概述及构造方法
-
是文件和目录路径名的抽象表示
-
文件和目录是可以通过File封装成对象(私有的)的
-
对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已
它可以是存在的、也可以是不存在的—将来是要通过具体的操作把这个路径的内容转换为具体存在的
-
File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法
-
File类的静态变量
-
File类的构造方法:
方法名 说明 File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例 File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例 -
方法注意事项:
-
示例代码
public class FileDemo01 { public static void main(String[] args) { //File(String pathname): 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例 File f1 = new File("E:\\wedu\\java.txt"); System.out.println(f1); //File(String parent, String child): 从父路径名字符串和子路径名字符串创建新的 File实例 File f2 = new File("E:\\wedu","java.txt"); System.out.println(f2); //File(File parent, String child): 从父抽象路径名和子路径名字符串创建新的 File实例 File f3 = new File("E:\\wedu"); File f4 = new File(f3,"java.txt"); System.out.println(f4); } }
1.2 绝对路径和相对路径
- 绝对路径
是一个完整的路径,从盘符开始
- 相对路径
是一个简化的路径,相对当前项目下的路径
-
注意:
-
路径是不区分大小写
-
路径中的文件名称分隔符vindows使用反斜杠
但是反斜杠在代码里是转义字符,因此用两个反斜杠代表一个普通的反斜杠
-
(在idea中也可用一个正斜杠:File file3 = new File("模块名/a.txt");)
- 在写相对路径时,是相对当前项目的根目录,因此如果添加文件/文件夹时
- 如果是单个,就不需要加斜杠;如果是多级,则最左边的不需要加斜杠
- 如果需要在当前项目的根目录下的前一个目录下创建新文件或文件夹,可以在相对路径前加一个`'../'`代表退回上一级
- 如果需要在盘符下创建或删除,用一个斜杠就行`/`
1.3 File类创建功能
- 方法分类:
方法名 | 说明 |
---|---|
public boolean createNewFile() | 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件 |
public boolean mkdir() | 创建由此抽象路径名命名的目录 |
public boolean mkdirs() | 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录 |
- 示例代码:
public class FileDemo02 {
public static void main(String[] args) throws IOException {
//需求1:我要在E:\\wedu目录下创建一个文件java.txt
File f1 = new File("E:\\wedu\\java.txt");
System.out.println(f1.createNewFile());
System.out.println("--------");
//需求2:我要在E:\\wedu目录下创建一个目录JavaSE
File f2 = new File("E:\\wedu\\JavaSE");
System.out.println(f2.mkdir());
System.out.println("--------");
//需求3:我要在E:\\wedu目录下创建一个多级目录JavaWEB\\HTML
File f3 = new File("E:\\wedu\\JavaWEB\\HTML");
// System.out.println(f3.mkdir());
System.out.println(f3.mkdirs());
System.out.println("--------");
//需求4:我要在E:\\wedu目录下创建一个文件javase.txt
File f4 = new File("E:\\wedu\\javase.txt");
// System.out.println(f4.mkdir());
System.out.println(f4.createNewFile());
}
}
1.4 File类删除、判断和获取功能
- 方法分类
- 删除
方法名 | 说明 |
---|---|
public boolean delete() | 删除由此抽象路径名表示的文件或目录 |
- 判断
方法名 | 说明 |
---|---|
public boolean isDirectory() | 测试此 抽象路径名表示的 File是否为目录 |
public boolean isFile() | 测试此抽象路径名表示的 File是否为文件 |
public boolean exists() | 测试此抽象路径名 表示的 File 是否存在 |
- 获取功能
方法名 | 说明 |
---|---|
public String getAbsolutePath() | 返回此抽象路径名的 绝对路径名 字符串 |
public String getPath() | 将此抽象路径名 转换为 路径名 字符串 |
public String getName() | 返回由此抽象路径名表示的 文件或目录的名称 |
public File[] listFiles() | 返回此抽象路径名表示的 目录中的文件 和 目录的File对象数组 |
public long lengh() | 返回由此File表示的文件的长度(文件的大小) |
-
示例代码
public class FileDemo04 { public static void main(String[] args) { //创建一个File对象 File f = new File("myFile\\java.txt"); // public boolean isDirectory():测试此抽象路径名表示的File是否为目录 // public boolean isFile():测试此抽象路径名表示的File是否为文件 // public boolean exists():测试此抽象路径名表示的File是否存在 System.out.println(f.isDirectory()); System.out.println(f.isFile()); System.out.println(f.exists()); // public String getAbsolutePath():返回此抽象路径名的绝对路径名字符串 // public String getPath():将此抽象路径名转换为路径名字符串 // public String getName():返回由此抽象路径名表示的文件或目录的名称 System.out.println(f.getAbsolutePath()); System.out.println(f.getPath()); System.out.println(f.getName()); System.out.println("--------"); // public File[] listFiles():返回此抽象路径名表示的目录中的文件和目录的File对象数组 File f2 = new File("E:\\wedu"); File[] fileArray = f2.listFiles(); for(File file : fileArray) { // System.out.println(file); // System.out.println(file.getName()); if(file.isFile()) { System.out.println(file.getName()); } } } }
1.5 File类的递归遍历
- 对File类对象进行遍历,是将其绝对路径中的子文件/目录以数组形式进行遍历
- File类遍历(文件夹)目录功能
- 常用方法:
方法名 | 方法说明 |
---|---|
public string[] list() | 返回一个string数组 表示该File目录中的所有子文件或目录 |
public File[] listFiles() | 返回一个File数组 表示该File目录中的所有的子文件或目录 |
- 注意事项:
- 以上两个方法遍历的都是构造方法中给出的目录
- 如果构造方法中给出的目录的路径不存在,会抛出空指针异常
- 如果构造方法中给出的路径不是一个目录,也会抛出空指针异常
- 以上两个方法遍历的都是构造方法中给出的目录
- 代码示例:
public static void main(String[] args) throws IOException {
File file = new File("E:/IDEA/Test");
getAllFile(file);
}
//递归思想的方法
private static void getAllFile(File file) {
System.out.println("当前路径:"+file);
File[] files = file.listFiles();
for (File file1 : files) {
if(file1.isDirectory()){//判断是否是目录
getAllFile(file1);
}else {
System.out.println(file1);
}
二、IO流概述
在前言的部分已经介绍了IO流的分类与结构图解,可以相结合来看
-
IO流介绍
-
IO流概念和分类的图解
-
IO流的使用场景
- 如果操作的是纯文本文件,优先使用字符流
- 如果操作的是图片、视频、音频等二进制文件,优先使用字节流
- 如果不确定文件类型,优先使用字节流,字节流是万能的流
2.1 字节流与字符流
2.1.1 字节流
-
字节流基类的常用方法:
- InputStream抽象基类定义的所有子类共性的方法
方法名及返回值 说明 void close() 关闭此输入流并释放与此流相关联的任何系统资源 int read() 从输入流中读取数据的下一个字节 int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中 - OutputStream抽象基类定义的所有子类共性的方法
方法名及返回值 说明 void close() 关闭此输出流并释放与此流相关联的任何系统资源 void flush() 刷新此输出流并强制任何缓冲的输出字节被写出 void write(byte[] b) 将 b.length字节从指定的字节数组写入此输出流 void write(byte[] b, int off, int len) 从指定的字节数组写入 len字节,从 偏移量 off 开始输出到此输出流 abstract void write(int b) 将指定的字节写入此输出流 -
字节流基类的子类
子类名特点:子类名称都是以其父类名作为子类名的后缀
2.1.2 字节流
Writer: 用于写入字符流的抽象父类
Reader: 用于读取字符流的抽象父类,顶层父类
2.2 文件与IO流
2.2.1 文件字节输出流
文件字节输出流FileOutputStream类的构造方法:
- Fileoutputstream(string name) 创建一个向具有指定名称的文件中写入数据的输出文件流Fileoutputstream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流
- 参数:写入数据的目的地
- string name:目的地是一个文件的路径
- File file:目的地是一个文件
- 构造方法:
字节输出流的使用步骤(重点): - 创建一个Fileoutputstream对象,构造方法中传递写入数据的目的地,即想要保存数据的文件的绝对路径
- 调用FileOutputstream对象中的write方法,把数据写入到文件中
- 释放资源(流使用会占用一定的内存,因此使用完毕要把内存清空,提高程序的效率)
- 示例代码
public class FileOutputStreamDemo01 {
public static void main(String[] args) throws IOException {
//创建字节输出流对象
/*
注意点:
1.如果文件不存在,会帮我们创建
2.如果文件存在,会把文件清空
*/
//FileOutputStream(String name):创建文件输出流以指定的名称写入文件
FileOutputStream fos = new FileOutputStream("myByteStream\\fos.txt");
//void write(int b):将指定的字节写入此文件输出流
fos.write(97);
// fos.write(57);
// fos.write(55);
//最后都要释放资源
//void close():关闭此文件输出流并释放与此流相关联的任何系统资源。
fos.close();
}
}
- 存储数据和记事本的原理:
2.2.2 文件字节输入流
-
文件字节输入流
-
FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名
-
作用:把硬盘文件中的数据,读取到内存使用
-
FileInputStream类的构造方法
-
字节输入流读取数据的步骤
- 创建字节输入流对象
- 调用字节输入流对象的读数据方法
- 释放资源
-
示例代码
2.2.3 文件字符输入输出流
-
FileWriter: 用于写入字符流的常用子类,直接继承OutputStreamWriter类
-
FileWriter作用:把内存中字符数据写入到文件中
-
构造方法
方法名 | 说明 |
---|---|
FileWriter(File file) | 根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(File file, boolean append) | 根据给定的 File 对象构造一个 FileWriter 对象 |
FileWriter(String fileName) | 根据给定的文件名构造一个 FileWriter 对象 |
FileWriter(String fileName, boolean append) | 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 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) | 写一个字符串的一部分 |
- 刷新和关闭的方法
方法名 | 说明 |
---|---|
flush() | 刷新流,之后还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
-
字符输出流的使用步骤:(与字节流有不同)
-
创建 Filewriter对象,构造方法中绑定要写入数据的目的地
-
使用 Filelriter 中的 方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
-
使用 Filelriter 中的 方法flush,把内存缓冲区中的数据,刷新到文件中
-
释放资源(会先把内存缓冲区中的数据刷新到文件中)
-
代码演示
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("myCharStream\\a.txt");
//void write(int c):写一个字符
// fw.write(97);
// fw.write(98);
// fw.write(99);
//void writ(char[] cbuf):写入一个字符数组
char[] chs = {'a', 'b', 'c', 'd', 'e'};
// fw.write(chs);
//void write(char[] cbuf, int off, int len):写入字符数组的一部分
// fw.write(chs, 0, chs.length);
// fw.write(chs, 1, 3);
//void write(String str):写一个字符串
// fw.write("abcde");
//void write(String str, int off, int len):写一个字符串的一部分
// fw.write("abcde", 0, "abcde".length());
fw.write("abcde", 1, 3);
//释放资源
fw.close();
}
}
- FileReader: 用于读取字符流的常用子类
- 构造方法
方法名 | 说明 |
---|---|
FileReader(File file) | 在给定从中读取数据的 File 的情况下创建一个新 FileReader |
FileReader(String fileName) | 在给定从中读取数据的文件名的情况下创建一个新 FileReader |
-
成员方法继承自父类InputStreamReader
方法名 说明 int read() 一次读一个字符数据 int read(char[] cbuf) 一次读一个字符数组数据 void close() 关闭流并释放与之相关联的任何系统资源 -
代码演示(与字节输入流一样)
public class InputStreamReaderDemo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("myCharStream\\b.txt"); int read():一次读一个字符数据 int ch; while ((ch=fr.read())!=-1) { System.out.print((char)ch); } //int read(char[] cbuf):一次读一个字符数组数据 char[] chs = new char[1024]; int len; while ((len = fr.read(chs)) != -1) { System.out.print(new String(chs, 0, len)); } //释放资源 fr.close(); } }
三、缓冲流
3.1 字节缓冲流
-
字节缓冲流介绍
-
BufferOutputStream:该类实现缓冲输出流
通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
-
BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组
当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
-
-
构造方法:
方法名 说明 BufferedOutputStream(OutputStream out) 创建字节缓冲输出流对象 BufferedInputStream(InputStream in) 创建字节缓冲输入流对象 -
示例代码
public class BufferStreamDemo { public static void main(String[] args) throws IOException { //字节缓冲输出流:BufferedOutputStream(OutputStream out) BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\bos.txt")); //写数据 bos.write("hello\r\n".getBytes());//调用String类的方法,将其转化为字节数组 bos.write("world\r\n".getBytes()); //释放资源 bos.close(); //字节缓冲输入流:BufferedInputStream(InputStream in) BufferedInputStream bis = new BufferedInputStream(new FileInputStream("myByteStream\\bos.txt")); //一次读取一个字节数据 // int by; // while ((by=bis.read())!=-1) { // System.out.print((char)by); // } //一次读取一个字节数组数据 byte[] bys = new byte[1024]; int len; while ((len=bis.read(bys))!=-1) { System.out.print(new String(bys,0,len)); } //释放资源 bis.close(); } }
3.2 字符缓冲流
-
字符缓冲流介绍
-
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,可以指定缓冲区大小,或者可以接受默认大小。默认值足够大,可用于大多数用途
-
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途
-
-
构造方法
方法名 说明 BufferedWriter(Writer out) 创建字符缓冲输出流对象 BufferedReader(Reader in) 创建字符缓冲输入流对象 -
代码演示
public class BufferedStreamDemo01 { public static void main(String[] args) throws IOException { //BufferedWriter(Writer out) BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\bw.txt")); bw.write("hello\r\n"); bw.write("world\r\n"); bw.close(); //BufferedReader(Reader in) BufferedReader br = new BufferedReader(new FileReader("myCharStream\\bw.txt")); //一次读取一个字符数据 // int ch; // while ((ch=br.read())!=-1) { // System.out.print((char)ch); // } //一次读取一个字符数组数据 char[] chs = new char[1024]; int len; while ((len=br.read(chs))!=-1) { System.out.print(new String(chs,0,len)); } br.close(); } }