深入理解Java IO流:从File类到字节流与字符流
引言
在Java中,IO(输入/输出)操作是程序与外部世界交互的重要方式。
其中,File类是进行文件操作的基础,而字节流和字符流则是数据传输的两种主要方式。
本文将深入探讨这些概念及其应用。
一、 File类详解:
介绍:
File类是Java中表示文件和文件路径名的抽象表示形式。它不仅仅代表一个存在的文件或目录,还可以代表一个不存在的文件或目录,用于表示未来可能创建的文件或目录。
概念:
- 什么是文本文档?
- 能用记事本打开不
乱码
就是文本文档,如 txt、html 、 css,.doc 不属于文本文档
- 能用记事本打开不
- 路径
- D:\XiuLian\java\1.txt 中的父路径是谁?
- 父路径是:D:\XiuLian\java ,而非 java,java只是 1,txt 的文件夹
- 分隔符
- 路径名称分隔符
- Windows : \
- Linux : /
- 路径分隔符:一个路径和其他路径之间的分隔符
- ;
- 路径名称分隔符
- 文件和目录(文件)路径名的抽象表示
- 简单理解
-. 我们在创建File
对象的时候,需要传递一个路径,这个路径定为到哪个文件或者文件夹上,我们的File
就代表哪个对象,如 File fle = new File(“D:\XiuLian\java\1.txt”)
1、File类中的静态成员:
- pathSeparator:
- static string pathSeparator: 与系统有关的路径分隔符,用于分隔文件路径。
- separator :
- static String separator: 与系统有关的名称分隔符,用于分隔目录和文件名。
/**
* File中的静态方法
* static string pathSeparator;
* static String separator;
* */
@Test
public void file01() {
// static string pathSeparator: 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
String pathSeparator = File.pathSeparator;
System.out.println("pathSeparator = " + pathSeparator); // ;
// static String separator: 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
String separator = File.separator;
System.out.println("separator = " + separator); // \
}
运行结果:
pathSeparator = ;
separator = \
2、File类的构造方法
File 类提供了多种构造方法,用于创建File对象。其中,最常见的是通过文件路径字符串或父路径与子路径组合来创建。
parent : 父路径
child :子路径
File(string parent,string child) 根据所填写的路径创建 File 对象
parent : 父路径,是一个 File 对象
child :子路径
File(File parent,string child) 根据所填写的路径创建 File 对象
pathnam : 直接指定路径
File(String pathname) 根据所填写的路径创建 File 对象
@Test
public void file02(){
File file1 = new File("C:\\Users\\11111\\OneDrive\\图片\\本机照片","01.jpg");
System.out.println("file4 : "+file1);
File file2 = new File("C:\\Users\\11111\\OneDrive\\图片\\本机照片");
File file3 = new File(file2,"01.jpg");
System.out.println("file3 : "+file3);
File file4 = new File("C:\\Users\\11111\\OneDrive\\图片\\本机照片\\01.jpg");
System.out.println("file : "+file4);
// 注意 : File 对象可以传递不存在的路径
}
运行结果:
file1 : C:\\Users\\11111\\OneDrive\\图片\\本机照片\\01.jpg
file3 : C:\\Users\\11111\\OneDrive\\图片\\本机照片\\01.jpg
file4 : C:\\Users\\11111\\OneDrive\\图片\\本机照片\\01.jpg
3、File类的主要方法:
string getAbsolutePath()->获取文件的绝对路径
string getPath() -> 获取封装时的路径
String getName() ->获取文件或目录的名称
Long length() -> 获取文件的长度(以字节为单位)
@Test
public void file03(){
File file1 = new File("1.txt");
System.out.println("file1.getAbsolutePath() : "+file1.getAbsolutePath());
File file2 = new File("IO\\1.txt");
System.out.println("file2.getPath() : "+file2.getPath());
File file3 = new File("C:\\Users\\29170\\OneDrive\\图片\\本机照片\\01.jpg");
System.out.println("file3.length() : "+file3.length());
}
运行结果:
file1.getAbsolutePath() : D:\XiuLian\Work\practice\1.txt
file2.getPath() : IO\1.txt
file3.length() : 334591
4、File 创建方法:
/**
* 创建方法
* boolean createNewFile() -> 创建文件
* 如果要创建的文件之前有,创建失败,返回 false
* 如果要创建的文件之前没有,创建成功,返回 true
* boolean mkdirs() -> 创建文件夹 (目录) 既可以创建多级文件夹,还可以创建单级文件夹
* 如果要创建的目录之前有,创建失败,返回 false
* 如果要创建的目录之前没有,创建成功,返回 true
* */
@Test
public void file04() throws IOException {
File file1 = new File("D:\\XiuLian\\Work\\1.txt");
boolean newFile = file1.createNewFile();
System.out.println("file.createNewFile : "+newFile);
File file2 = new File("D:\\XiuLian\\Work\\nb");
boolean mkdir = file2.mkdirs();
System.out.println("file.mkdirs : "+ mkdir);
}
运行结果
file.createNewFile : false
file.mkdirs : true
5、File 删除方法:
/**
* boolean delete()->删除文件或者文件,删除文件不走回收站
* 如果删除的是文件夹,只能删除空的,删除文件夹不走回收站
* */
@Test
public void file05() {
File file1 = new File("D:\\XiuLian\\Work\\1.txt");
System.out.println("file1.delete : " +file1.delete());
}
运行结果
file1.delete : true
6、File 类的判断方法:
/**
* boolean isDirectory() -> 判断是否为文件夹
* boolean isFile() -> 判断是否为文件
* boolean exists() -> 判断文件或者文件夹是否存在
* */
@Test
public void file06() throws IOException {
File file1 = new File("D:\\XiuLian\\Work\\1.txt");
System.out.println("file1.isDirectory : " + file1.isDirectory());
boolean newFile = file1.createNewFile();
System.out.println("file1.isFile : " + file1.isFile());
System.out.println("file1.exists : " + file1.exists());
}
运行结果:
file1.isDirectory : false
file1.isFile : true
file1.exists : true
7、File类的遍历方法:
/**
* String[] list() -> 遍历指定的文件夹,返回的是string数组
* File[] ListFiLes()-> 遍历指定的文件夹,返回的是Fi1e数组 ->这个推荐使用
* */
@Test
public void file07() throws IOException {
File file1 = new File("C:\\Users\\29170\\OneDrive\\图片\\本机照片");
String[] list = file1.list();
Arrays.stream(list).forEach(System.out::println);
System.out.println("--------------------------");
File[] files = file1.listFiles();
Arrays.stream(files).forEach(System.out::println);
}
运行结果:
01.jpg
02.jpg
03.png
04.jpg
05.jpg
--------------------------
C:\Users\xxx\OneDrive\图片\本机照片\01.jpg
C:\Users\xxx\OneDrive\图片\本机照片\02.jpg
C:\Users\xxx\OneDrive\图片\本机照片\03.png
C:\Users\xxx\OneDrive\图片\本机照片\04.jpg
C:\Users\xxx\OneDrive\图片\本机照片\05.jpg
8、File 的练习:
- 创建 File 对象,指定要遍历的文件夹路径
- 调用 File 遍历方法,遍历文件夹,返回 File 数组
- 遍历File数组,在遍历的过程中判断,如果是文件,获取文件名,判断是否是已 .jpg 结尾的,并打印
@Test
public void file08() throws IOException {
// 1.创建 File 对象,指定要遍历的文件夹路径
File file = new File("C:\\Users\\29170\\OneDrive\\图片\\本机照片");
method(file);
}
public static void method(File file){
File[] files = file.listFiles();
assert files != null;
for (File i : files) {
if (i.isFile()){
String path = i.getPath();
if (path.endsWith(".jpg")) System.out.println(path);
}else {
method(i);
}
}
}
练习二:删除日志文件
- 删除指定文件的日志文件(日志只保存七天,超过七天的文件删除)
- 日志的命名格式位 ABC.2024-01-01.txt
- 要求文件夹下的子文件夹中的日志也要删除
@Test
public void testFileDelete() {
LocalDate today = LocalDate.now();
// 减去7天得到7天前的日期
LocalDate sevenDaysAgo = today.minusDays(7);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 注意这里使用小写dd
String formattedDate = sevenDaysAgo.format(formatter);
method(new File("D:\\logs"), formattedDate);
}
public static void method(File file, String cutoffDateStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate cutoffDate = LocalDate.parse(cutoffDateStr, formatter);
File[] files = file.listFiles();
if (files == null) return; // 目录为空或访问权限问题等情况,直接返回
// 创建一个正则表达式模式,用于从文件名中提取日期部分
Pattern datePattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
// 遍历目录下的所有文件和子目录
for (File f : files) {
// 如果是文件
if (f.isFile()) {
// 检查文件扩展名是否为.txt
if (f.getName().endsWith(".txt")) {
// 使用正则表达式匹配文件名中的日期部分
Matcher matcher = datePattern.matcher(f.getName());
// 如果找到了匹配的日期
if (matcher.find()) {
// 提取文件名中的日期字符串
String fileDateStr = matcher.group(0);
// 将提取的日期字符串解析为LocalDate对象
LocalDate fileDate = LocalDate.parse(fileDateStr, formatter);
// 如果文件日期早于截止日期
if (fileDate.isBefore(cutoffDate)) {
// 尝试删除文件
boolean deleted = f.delete();
// 根据删除结果输出相应的信息
if (deleted) System.out.println("Deleted file: " + f.getPath());
}
}
}
} else if (f.isDirectory()) {
// 如果是目录,则递归调用method函数
method(f, cutoffDateStr);
}
}
}