系列二、IO流 - 文件

一、概述

        文件对我们并不陌生,简单的讲文件就是保存数据的地方,比如大家经常使用的word文档,txt文件,excel文件,mp3音乐文件,mp4视频文件...等等,它既可以是一张图片,也可以是一段视频,一段声音...

二、文件流

        文件在程序中是以流的形式来操作的。

流:数据在数据源(文件)和程序(内存)之间经历的路径

输入流:数据从数据源(文件)到程序(内存)的路径

输出流:数据从程序(内存)到数据源(文件)的路径

三、File

3.1、概述

java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

3.2、构造方法

# 通过将给定的 路径名字符串 转换为抽象路径名来创建新的File实例
public File(String pathname) 

# 从父路径名字符串和子路径名字符串创建新的File实例
public File(String parent, String child)

# 从父抽象路径名和子路径名字符串创建新的File实例
public File(File parent, String child)

3.3、常用构造方法

// 文件路径名
String pathname = "D:\\三国演义.txt";
File file1 = new File(pathname); 

// 文件路径名
String pathname2 = "D:\\四大名著\\水浒传.txt";
File file2 = new File(pathname2); 

// 通过父路径和子路径字符串
String parent = "D:\\四大名著";
String child = "红楼梦.txt";
File file3 = new File(parent, child);

// 通过父级File对象和子路径字符串
File parentDir = new File("D:\\四大名著");
String child = "西游记.txt";
File file4 = new File(parentDir, child);

3.4、说明

  • 一个File对象代表硬盘中实际存在的一个文件或者目录
  • 无论该路径下是否存在文件或者目录,都不影响File对象的创建

3.5、常用API

3.5.1、获取功能API

# 获取文件名字
getName()

# 获取绝对路径,包含盘符
getAbsolutePath()

# 获取父级目录
getParent()

# 获取文件大小(单位字节,UTF-8编码下,一个英文字符占用一个字节,一个中文占用三个字节)
length()

# 判断文件是否存在
exists()

# 判断是否是文件
isFile()

# 判断是都是文件夹
isDirectory()
@Test
public void getFileInfo() {
	File file = new File("D:\\三国演义.txt");
	if (file.exists()) {
		String fileName = file.getName();
		System.out.println("文件名称 = " + fileName);

		String absolutePath = file.getAbsolutePath();
		System.out.println("文件绝对路径 = " + absolutePath);

		String parentPath = file.getParent();
		System.out.println("文件父级目录 = " + parentPath);

		// 获取文件大小(UTF-8编码下,一个英文字母占用1个字节,一个中文汉字占用3个字节)
		long size = file.length();
		System.out.println("文件大小(单位字节) = " + size);

		boolean exists = file.exists();
		String result = exists ? "存在" : "不存在";
		System.out.println("文件是否存在 = " + result);

		boolean isFile = file.isFile();
		String isFileResult = isFile ? "是文件" : "不是文件";
		System.out.println("是否是文件 = " + isFileResult);

		boolean isDirectory = file.isDirectory();
		String isDirectoryResult = isDirectory ? "是目录" : "不是目录";
		System.out.println("是否是目录 = " + isDirectoryResult);

	} else {
		System.out.println("文件不存在");
	}
}
文件名称 = 三国演义.txt
文件绝对路径 = D:\三国演义.txt
文件父级目录 = D:\
文件大小(单位字节) = 134
文件是否存在 = 存在
是否是文件 = 是文件
是否是目录 = 不是目录

3.5.2、绝对路径和相对路径API

绝对路径:从盘符开始的路径,这是一个完整的路径

相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用

/**
 * 测试相对路径和绝对路径
 */
@Test
public void test2() {
	File file1 = new File("D:\\三国演义.txt");
	System.out.println("file1 absolutePath = " + file1.getAbsolutePath());
	System.out.println("file1 path = " + file1.getPath());

	File file2 = new File("朝花夕拾.txt");
	System.out.println("file2 absolutePath = " + file2.getAbsolutePath());
	System.out.println("file2 path = " + file2.getPath());

	File file3 = new File("狂人日记.txt");
	System.out.println("file3 absolutePath = " + file3.getAbsolutePath());
	System.out.println("file3 path = " + file3.getPath());

	File file4 = new File("呐喊.txt");
	System.out.println("file4 absolutePath = " + file4.getAbsolutePath());
	System.out.println("file4 path = " + file4.getPath());
}

3.5.3、创建删除API

# 当且仅当具有该名称的文件尚不存在时,创建一个新的空文件
public boolean createNewFile()

# 删除由此File表示的文件或目录
public boolean delete()

# 创建由此File表示的目录
public boolean mkdir()

# 创建由此File表示的目录,包括任何必需但不存在的父目录
public boolean mkdirs()

# 注意事项
delete方法,如果此File表示目录,则目录必须为空才能删除

3.5.4、目录遍历API

# 返回一个String数组,表示该File目录中的所有子文件或目录
public String[] list()

# 返回一个File数组,表示该File目录中的所有的子文件或目录
public File[] listFiles()

四、综合练习

4.1、创建文件夹

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/22 10:15
 * @Description: 综合练习一:创建文件夹
 * 需求:在当前模块下的 现代小说\鲁迅全集文件夹 创建 彷徨.txt文件
 */
public class ComprehensiveExerciseDemo1 {
    public static void main(String[] args) throws IOException {
        File parent = new File("现代小说\\鲁迅全集");
        parent.mkdirs();
        File file = new File(parent,"彷徨.txt");
        boolean result = file.createNewFile();
        if (result) {
            System.out.println("创建成功");
        } else {
            System.out.println("创建失败");
        }
    }
}

4.2、查找文件(不考虑子文件夹)

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/22 10:29
 * @Description: 综合练习二:查找文件(不考虑子文件夹)
 * 需求:查找某一个文件夹中是否存在以 .avi 结尾的视频
 */
public class ComprehensiveExerciseDemo2 {
    public static void main(String[] args) {
        String dirPath = "现代小说\\鲁迅全集";
        File file = new File(dirPath);
        if (!file.exists() || !file.isDirectory()) {
            System.out.println("文件不存在或者不是目录");
            return;
        } else {
            boolean result = hasAvi(file);
            String message = result ? "包含" : "不包含";
            System.out.println(message); // 打印结果:不包含
        }
    }

    /**
     * 判断一个目录中是否存在以avi结尾的文件
     * @param file
     * @return
     */
    private static boolean hasAvi(File file) {
        File[] files = file.listFiles();
        for (File f : files) {
            // f依次表示dirPath文件夹里面每一个文件或者文件夹的路径
            if (f.isFile() && f.getName().endsWith(".avi")) {
                return true;
            }
        }
        return false;
    }
}

4.3、查找文件(考虑子文件夹)

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/22 10:29
 * @Description: 综合练习三:查找文件(考虑子文件夹)
 * 需求:查找电脑中是否存在以 .avi 结尾的视频
 */
public class ComprehensiveExerciseDemo3 {
    public static void main(String[] args) {
        findAvi();
    }

    public static void findAvi() {
        // 获取本地所有的盘符
        File[] fileArray = File.listRoots();
        System.out.println(Arrays.asList(fileArray));
        for (File file : fileArray) {
            findAvi(file);
        }
    }

    public static void findAvi(File file) {
        File[] files = file.listFiles();
        if (ObjectUtil.isNotNull(files)) {
            for (File f : files) {
                if (f.isFile()) {
                    if (f.getName().endsWith(".avi")) {
                        System.out.println(f.getAbsolutePath());
                    }
                } else {
                    findAvi(f);
                }
            }
        }
    }


}

4.4、删除多级文件夹

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/22 10:51
 * @Description: 删除多级文件夹
 * 需求:删除 当前项目的 现代小说 文件夹
 */
public class ComprehensiveExerciseDemo4 {
    public static void main(String[] args) {
        String dirPath = "现代小说";
        File file = new File(dirPath);
        delete(file);
    }

    public static void delete(File file) {
        if (!file.exists()) {
            System.out.println("目录不存在");
            return;
        } else {
            // 1、先删除文件夹里面所有的内容
            File[] files = file.listFiles();
            for (File f : files) {
                // 如果是文件直接删除
                if (f.isFile()) {
                    f.delete();
                } else {
                    // 如果是文件夹,递归
                    delete(f);
                }
            }
            // 2、所有文件都删除完毕后再删除自己
            file.delete();
        }
    }
}

4.5、统计大小

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/22 11:05
 * @Description: 统计大小
 * 需求:统计 D:\开源项目\vhr 文件夹的总大小
 */
public class ComprehensiveExerciseDemo5 {
    public static void main(String[] args) {
        String dirPath = "D:\\开源项目\\vhr";
        File file = new File(dirPath);
        if (!file.exists()) {
            System.out.println("文件不存在");
            return;
        }
        long size = getSize(file);
        // 控制台打印:D:\开源项目\vhr 文件夹总大小为:16574285
        System.out.println(dirPath + " 文件夹总大小为:" + size);
    }

    /**
     * 获取某个文件夹中文件的总大小(单位:字节)
     * @param file
     * @return
     */
    public static long getSize(File file) {
        long size = 0;
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isFile()) {
                size += f.length();
            } else {
                size += getSize(f);
            }
        }
        return size;
    }
}

4.6、统计文件夹中文件的个数

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/22 11:22
 * @Description: 综合练习六:统计文件的个数(考虑子文件夹)
 * 需求:统计当前项目下 我的收藏 文件夹下各个类型文件的个数
 */
public class ComprehensiveExerciseDemo6 {
    public static void main(String[] args) {
        String dirPath = "我的收藏";
        File file = new File(dirPath);
        if (!file.exists()) {
            System.out.println("文件不存在");
            return;
        }
        HashMap<String,Integer> resultMap = getDetail(file);
        // 控制台打印 {txt=4, mp3=1, pdf=1, avi=5, webp=1}
        System.out.println(resultMap);
    }

    public static HashMap<String, Integer> getDetail(File file) {
        HashMap<String, Integer> resultMap = new HashMap<>();
        for (File f : file.listFiles()) {
            if (f.isFile()) {
                // 三国演义.txt
                String name = f.getName();
                String[] arr = name.split("\\.");
                if (arr.length >= 2) {
                    String suffix = arr[arr.length - 1];
                    if (resultMap.containsKey(suffix)) {
                        Integer count = resultMap.get(suffix);
                        count++;
                        resultMap.put(suffix,count);
                    } else {
                        resultMap.put(suffix,1);
                    }
                }
            } else {
                /*
                     sonResultMap里面是子文件夹中每一个文件的个数
                     resultMap : {txt=4, mp3=1, pdf=1, avi=1, webp=1}
                     sonResultMap: {avi=4}
                 */
                HashMap<String,Integer> sonResultMap = getDetail(f);
                // 遍历sonResultMap,将里面的值累加到resultMap中
                Set<Map.Entry<String, Integer>> entries = sonResultMap.entrySet();
                for (Map.Entry<String, Integer> entry : entries) {
                    String key = entry.getKey();
                    Integer value = entry.getValue();
                    if (resultMap.containsKey(key)) {
                        Integer count = resultMap.get(key);
                        count += value;
                        resultMap.put(key,count);
                    } else {
                        resultMap.put(key,value);
                    }
                }
            }
        }


        return resultMap;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值