一、File类
1.1 File类概述和构造方法
-
File
类介绍- 它是文件和目录路径名的抽象表示
- 文件和目录是可以通过
File
封装成对象的 - 对于
File
而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已。- 它可以是存在的,也可以是不存在的
- 将来是要通过具体的操作把这个路径的内容转换为具体存在的
-
File类的构造方法
方法名 说明 File(String pathname)
通过将给定的路径名字符串转换为抽象路径名来创建新的 File
实例File(String parent, String child)
将父路径名字符串和子路径名字符串进行拼接,创建新的 File
实例File(File parent, String child)
将父抽象路径名和子路径名字符串进行拼接,创建新的 File
实例 -
示例代码
import java.io.File;
public class Demo01 {
public static void main(String[] args) {
// File(String pathname)
// 通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
String s1 = "E:\\java";
File file1 = new File(s1);
System.out.println(file1); // E:\java
// File(String parent, String child)
// 从父路径名字符串和子路径名字符串创建新的File实例
String s2 = "java.txt";
File file2 = new File(s1, s2);
System.out.println(file2); // E:\java\java.txt
// File(File parent, String child)
// 从父抽象路径名和子路径名字符串创建新的File实例
String s3 = "a.txt";
File file3 = new File(file1, s3);
System.out.println(file3); // E:\java\a.txt
}
}
1.2 绝对路径和相对路径
-
绝对路径
- 是一个完整的路径,从盘符开始
-
相对路径
- 是一个简化的路径,相对当前项目下的路径
- 注意这里是当前项目下,不是当前模块下
1.3 File类创建功能
-
方法分类
方法名 说明 public boolean createNewFile()
当具有该名称(路径+文件名)的文件不存在时,创建一个由该抽象路径名命名的新空文件 public boolean mkdir()
创建由此抽象路径名命名的目录,只能创建单级目录 public boolean mkdirs()
创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录 -
示例代码
import java.io.File;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) throws IOException {
// public boolean createNewFile()
// 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
/*
说明:
1、如果文件存在,则创建失败,返回false
2、如果文件不存在,创建成功,返回true
3、创建时不管文件是否有后缀名
*/
File file1 = new File("E:\\java.txt");
boolean result = file1.createNewFile();
System.out.println(result); // true
boolean result2 = file1.createNewFile();
System.out.println(result2); // false
// public boolean mkdir()
// 创建由此抽象路径名命名的目录
/*
说明:
1、只能创建单级文件夹,不能创建多级文件夹或创建文件,所以了解即可
*/
File file2 = new File("E:\\java");
boolean result3 = file2.mkdir();
System.out.println(result3);
// public boolean mkdirs()
// 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
/*
说明:
1、既可以创建多级文件夹,也可以创建单级文件夹
2、不管有没有后缀,只能创建文件夹
*/
File file3 = new File("E:\\hello\\world");
boolean result4 = file3.mkdirs();
System.out.println(result4);
}
}
1.4 File类删除功能
-
方法分类
方法名 说明 public boolean delete()
删除由此抽象路径名表示的文件或目录 -
示例代码
import java.io.File;
import java.io.IOException;
public class Demo03 {
public static void main(String[] args) throws IOException {
// public boolean delete()
// 删除由此抽象路径名表示的文件或目录
/*
说明:
1、删除的文件或空文件夹不经过回收站
2、如果是文件或空文件夹,则可直接删除
3、如果删除的文件夹非空,则需先进入把内容都删除,然后删除空文件夹
*/
// 删除文件
File file = new File("E:\\java.txt");
boolean result1 = file.createNewFile();
boolean result2 = file.delete();
System.out.println(result1);
System.out.println(result2);
// 删除目录
File file1 = new File("E:\\hello\\world");
boolean result3 = file1.mkdirs();
System.out.println(result3);
// System.out.println(file1.delete());
File file2 = new File("E:\\hello");
System.out.println(file2.delete()); // hello文件夹不为空
}
}
1.5 File类判断和获取功能
-
判断功能
方法名 说明 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
对象数组 -
示例代码
import java.io.File;
import java.io.IOException;
public class Demo04 {
public static void main(String[] args) throws IOException {
File file = new File("demo\\dir1");
file.mkdirs();
File file2 = new File("demo\\file1");
file2.createNewFile();
// public boolean isDirectory()
// 测试此抽象路径名表示的File是否为目录
System.out.println(file.isDirectory());
// public boolean isFile()
// 测试此抽象路径名表示的File是否为文件
System.out.println(file2.isFile());
// public boolean exists()
// 测试此抽象路径名表示的File是否存在
System.out.println(file.exists());
// public String getAbsolutePath()
// 返回此抽象路径名的绝对路径名字符串
System.out.println(file.getAbsolutePath());
// public String getPath()
// 将此抽象路径名转换为路径名字符串
System.out.println(file.getPath());
// public String getName()
// 返回由此抽象路径名表示的文件或目录的名称
System.out.println(file.getName());
// public File[] listFiles()
// 返回此抽象路径名表示的目录中的文件和目录的File对象数组
File file3 = new File("E:\\");
File[] files = file3.listFiles();
for (File file1 : files) {
System.out.print(file1 + " ");
}
}
}
-
总结
-
File
获取和判断方法-
判断是否为目录/文件夹
-
判断是否存在
exists
-
获取文件和文件夹的名字
-
-
File[] listFiles()
进入文件夹,获取所有的文件和目录的File
对象,并用数组返回(包含隐含文件)-
当调用者是一个文件是,调用会返回
null
-
当调用者是一个空文件夹是,调用会返回一个长度为
0
的数组 -
当调用着是一个有权限才能进入的文件夹时,也会返回
null
-
-
1.6 File类练习一
-
案例需求
- 在当前模块下的
aaa
文件夹中创建一个a.txt
文件
- 在当前模块下的
-
实现步骤
- 创建
File
对象,指向当前模块下的aaa
文件夹 - 判断
aaa
文件夹是否存在,如果不存在则创建 - 创建
File
对象,指向aaa
文件夹下的a.txt
文件 - 创建这个文件
- 创建
-
代码实现
import java.io.File;
import java.io.IOException;
public class Test01 {
public static void main(String[] args) throws IOException {
// 创建File对象,指向aaa文件夹
File file = new File("filemodule\\aaa");
// 如果不存在则创建
if(!file.exists()){
file.mkdirs();
}
// 创建File对象,指向aaa文件夹下的文件
File file2 = new File(file, "a.txt");
file2.createNewFile(); // 存在则不创建
}
}
1.7 File类练习二
-
案例需求
- 删除一个多级文件夹
-
实现步骤
- 定义一个方法,接收一个
File
对象 - 遍历这个
File
对象,获取它下边的每个文件和文件夹对象 - 判断当前遍历到的
File
对象是文件还是文件夹 - 如果是文件,直接删除
- 如果是文件夹,递归调用自己,将当前遍历到的
File
对象当做参数传递 - 参数传递过来的文件夹
File
对象已经处理完成,最后直接删除这个空文件夹
- 定义一个方法,接收一个
-
代码实现
import java.io.File;
public class Test02 {
public static void main(String[] args) {
// 创建file对象,指向准备好的文件夹
File file = new File("C:\\Users\\Administrator\\Desktop\\aaa");
if (file.exists()) {
deleteDir(file);
}
}
public static void deleteDir(File file) {
// 返回文件夹内所有文件和文件夹
File[] files = file.listFiles();
for (File file1 : files) {
// 如果是文件,直接删除
if (file1.isFile()) {
file1.delete();
} else {
// 如果是文件夹,递归调用
deleteDir(file1);
}
}
// 删除空文件夹
file.delete();
}
}
1.8 File类练习三
- 案例需求
- 统计一个文件夹中每种文件的个数并打印
- 代码实现
import java.io.File;
import java.util.HashMap;
public class Test03 {
public static void main(String[] args) {
File file = new File("E:\\hello");
HashMap<String, Integer> hashMap = new HashMap<>();
getCount(hashMap, file);
System.out.println(hashMap);
}
public static void getCount(HashMap<String, Integer> hashMap, File file) {
File[] files = file.listFiles();
for (File file1 : files) {
// 如果是文件,按.分隔
if (file1.isFile()) {
String name = file1.getName();
// split中\和.有特殊含义(正则),要用\\.来转义
String[] split = name.split("\\.");
if (split.length == 2) { // 防止没有后缀或者文件名中有多个.
if (hashMap.containsKey(split[1])) {
// 存在则计数加一
Integer count = hashMap.get(split[1]);
count++;
hashMap.put(split[1], count);
} else {
// 不存在则添加进hashMap
hashMap.put(split[1], 1);
}
}
}
if (file1.isDirectory()) {
// 如果是文件夹则递归调用
getCount(hashMap, file1);
}
}
}
}
二、字节流
2.1 IO流概述和分类
IO
流介绍IO
:输入/输出(Input/Output
)- 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
IO
流就是用来处理设备间数据传输问题的。常见的应用:文件复制、文件上传、文件下载
IO
流的分类- 按照数据的流向
- 输入流:读数据
- 输出流:写数据
- 按照数据类型来分
- 字节流
- 字节输入流
- 字节输出流
- 字符流
- 字符输入流
- 字符输出流
- 字节流
- 按照数据的流向
- IO流的使用场景
- 如果操作的是纯文本文件,优先使用字符流
- 如果操作的是图片、视频、音频等二进制文件,优先使用字节流
- 如果不确定文件类型,优先使用字节流。字节流是万能的流
2.2 字节流写数据
-
字节流抽象基类
InputStream
:这个抽象类是表示字节输入流的所有类的超类OutputStream
:这个抽象类是表示字节输出流的所有类的超类- 子类名特点:子类名称都是以其父类名作为子类名的后缀
-
字节输出流
FileOutputStream(String name)
:创建文件输出流以指定的名称写入文件
-
使用字节输出流写数据的步骤
- 创建字节输出流对象(调用系统功能创建了文件,创建字节输出流对象,让字节输出流对象指向文件)
- 调用字节输出流对象的写数据方法
write(int b)
- 释放资源
close()
(关闭此文件输出流并释放与此流相关联的任何系统资源)
-
示例代码
import java.io.FileOutputStream; import java.io.IOException; public class Demo05 { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("demo\\fos.txt"); // void write(int b) // 将指定的字节写入此文件输出流,一次写一个字节数据 fos.write(98); // void close():关闭此文件输出流并释放与此流相关联的任何系统资源。 fos.close(); } }
2.3 字节流写数据的三种方式
-
写数据的方法分类
方法名 说明 void write(int b)
将指定的字节写入此文件输出流 一次写一个字节数据 void write(byte[] b)
将 b.length
字节从指定的字节数组写入此文件输出流,一次写一个字节数组数据void write(byte[] b, int off, int len)
将 len
字节从指定的字节数组开始,从偏移量off
开始写入此文件输出流,一次写一个字节数组的部分数据(注意len
是几个字节,不是索引) -
示例代码
import java.io.FileOutputStream; import java.io.IOException; public class Demo06 { public static void main(String[] args) throws IOException { // void write(byte[] b) // 将 b.length字节从指定的字节数组写入此文件输出流 FileOutputStream fos = new FileOutputStream("demo\\fos.txt"); byte[] bytes = {1, 2, 3, 4, 5, 6}; fos.write(bytes); // void write(byte[] b, int off, int len) // 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流,一次写一个字节数组的部分数据 byte[] bytes1 = "abcde".getBytes(); fos.write(bytes1, 0, 3); fos.close(); } }
2.4 字节流写数据的两个小问题
-
字节流写数据如何实现换行
windows:\r\n
linux:\n
mac:\r
-
字节流写数据如何实现追加写入
public FileOutputStream(String name,boolean append)
- 创建文件输出流以指定的名称写入文件。如果第二个参数为
true
,则字节将写入文件的末尾(最后一个字符后,默认不换行)而不是开头
-
示例代码
import java.io.FileOutputStream; import java.io.IOException; public class Demo07 { public static void main(String[] args) throws IOException { // 实现字节流写数据的追加 FileOutputStream fos = new FileOutputStream("demo\\fos.txt", true); // 写数据并换行 fos.write("aaa".getBytes()); fos.write("\r\n".getBytes()); fos.write("aaa".getBytes()); fos.write("\r\n".getBytes()); // 释放资源 fos.close(); } }
2.5 字节流写数据加异常处理
-
异常处理格式
-
try-catch-finally
try{ 可能出现异常的代码; }catch(异常类名 变量名){ 异常的处理代码; }finally{ 执行所有清除操作; }
-
finally
特点- 被
finally
控制的语句一定会执行,除非JVM
退出
- 被
-
-
示例代码
import java.io.FileOutputStream; import java.io.IOException; public class Demo08 { public static void main(String[] args) { FileOutputStream fos = null; // 加入finally来实现释放资源 try { fos = new FileOutputStream("day18\\fos.txt"); fos.write("hello".getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { // 若FileOutputStream对象未成功创建则不需要关闭资源 if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
2.6 字节流读数据(read()
一次读一个字节数据)
-
字节输入流
FileInputStream(String name)
:通过打开与实际文件的连接来创建一个FileInputStream
,该文件由文件系统中的路径名name
命名
-
字节输入流读取数据的步骤
- 创建字节输入流对象
- 调用字节输入流对象的读数据方法
- 释放资源
-
示例代码
import java.io.FileInputStream; import java.io.IOException; public class Demo09 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("demo\\fos.txt"); int read = 0; // fis.read():读数据 // 当读取的数据为-1则停止读取 while ((read = fis.read()) != -1) { System.out.println((char) read); } // 释放资源 fis.close(); } }
2.7 字节流复制文件
-
实现步骤
- 复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
-
代码实现
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo10 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("E:\\hello\\world.txt"); FileOutputStream fos = new FileOutputStream("demo\\world.txt"); // 读取数据,循环写入 int read; while ((read = fis.read()) != -1) { fos.write(read); } // 释放资源 fos.close(); fis.close(); } }
2.8 字节流读数据(一次读一个字节数组数据)
-
一次读一个字节数组的方法
public int read(byte[] b)
:从输入流读取最多b.length
个字节的数据- 返回的是读入缓冲区的总字节数,也就是实际的读取字节个数
-
示例代码
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo11 { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("demo\\fos.txt"); FileOutputStream fos = new FileOutputStream("E:\\hello\\world.txt"); byte[] bytes = new byte[1024]; int len; // 本次读到的有效字节个数 // 循环读取 while ((len = fis.read(bytes)) != -1) { fos.write(bytes, 0, len); } fis.close(); fos.close(); } }
三、字节缓冲流
3.1 字节缓冲流构造方法
-
字节缓冲流介绍
BufferOutputStream
:该类实现缓冲输出流。- 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
BufferedInputStream
:创建BufferedInputStream
将创建一个内部缓冲区数组。- 当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
-
构造方法:
方法名 说明 BufferedOutputStream(OutputStream out)
创建字节缓冲输出流对象 BufferedInputStream(InputStream in)
创建字节缓冲输入流对象 - 注:不能使用字符串传参构造,必须传递字节流对象(因为字节缓冲流仅仅在内存中提供一个数组缓冲区)
-
示例代码
import java.io.*; public class Demo12 { public static void main(String[] args) throws IOException { // BufferedOutputStream(OutputStream out) // 创建字节缓冲输出流对象 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("demo\\fos.txt")); // 写数据并释放 bos.write("hello\r\n".getBytes()); bos.write("world\r\n".getBytes()); bos.close(); // BufferedInputStream(InputStream in) // 创建字节缓冲输入流对象 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day18\\fos.txt")); // 一次读取一个字节数组数据 byte[] bytes = new byte[1024]; int len; while ((len = bis.read(bytes)) != -1) { System.out.print(new String(bytes, 0, len)); } // 释放 bis.close(); } }