File

File概述

File可以表示文件的路径也可以表示文件夹的路径

如果我们需要将一个游戏文件保存在本地,我们需要用File确定保存文件的位置和用IO进行传输
路径

File类构造方法


File表示文件,创建出一个对象则表示创建出了一个文件,而输出文件则输出路径名,则路径名是文件的字符串表示

package com;

import java.io.File;

public class FileDimo1 {
    public static void main(String[] args) {
        /*
        public File(String pathname)   根据文件路径创建文件对象
        public File(String parent,String child) 根据父类路径名字符串和子类路径名字符串创建文件对象
        public File(File parent,String child)   根据父路径对应的文件对象和子路径名字符串创建文件对象
        C:\Users\alienware\Desktop\a.txt
         */
        //1.根据字符串表示的路径创建文件对象
        String str = " C:\\Users\\alienware\\Desktop\\a.txt";
        File f1 = new File(str);
        System.out.println(f1.toString());// C:\Users\alienware\Desktop\a.txt
        //2.根据父类路径字符串和子类路径字符串创建文件对象
        //父级路径:C:\Users\alienware\Desktop
        //子级路径:a.txt(完整文件名)
        String parent = "C:\\Users\\alienware\\Desktop";
        String child = "a.txt";
        File f2 = new File(parent,child);
        System.out.println(f2);//C:\Users\alienware\Desktop\a.txt
        //这里也可以用父级路径名和子级路径名进行拼接(这种方式不提倡使用)
        //1.java中\为文件分隔符有特殊含义需要用\\转义
        //2.如果我们的代码用在别的平台 如Linux使用\\链接java底层将不会将文件分隔符转化为别的平台的分隔符
        File f3 = new File("C:\\Users\\alienware\\Desktop"+"\\"+"a.txt");
        System.out.println(f3);
        //3.把一个File表示的路径和一个字符串表示的路径进行拼接
        File parent2 = new File("C:\\Users\\alienware\\Desktop");
        String child2 = "a.txt";
        File f4 = new File(parent2,child);
        System.out.println(f4);//C:\Users\alienware\Desktop\a.txt
    }
}


绝对路径是带盘符的。相对路径是不带盘符的,默认到当前项目下去找

File中常见成员方法

判断获取

package com;

import java.io.File;

public class FileDimo1 {
    public static void main(String[] args) {
        //判断的方法
        /*
        public boolean isDirectory()        判断此路径名表示的File是否为文件夹
        public boolean isFile()             判断此路径名表示的File是否为文件
        public boolean exists()             判断此路径名表示的File是否存在
         */
        //1.对一个文件的路径进行判断
        File f1 = new File("D:\\QQLicense.rtf");
        System.out.println(f1.isDirectory());//false
        System.out.println(f1.isFile());//true
        System.out.println(f1.exists());//true
        System.out.println("----------------------------------------------------");
      //2.对一个文件夹的路径进行判断
        File f2 = new File("D:\\WeChat");
        System.out.println(f2.isDirectory());//true
        System.out.println(f2.isFile());//false
        System.out.println(f2.exists());//true
        System.out.println("-----------------------------------------");
        //3.对一个不存在的路径进行判断
        File f3 = new File("D:\\abcd");
        System.out.println(f3.isDirectory());//false
        System.out.println(f3.isFile());//false
        System.out.println(f3.exists());//false
    }
}

相对路径可以理解为在当前编译器项目中的路径,决定路径则是在整个电脑中的路径

定义File文件可以使用相对路径也可以使用绝对路径

package com;

import java.io.File;

public class FileDimo1 {
    public static void main(String[] args) {
       /*
       获取方法:
       public long length()           返回文件的大小(字节数量)
       public String getAbsolutePath() 获取文件的绝对路径
       public String getPath()         返回定义文件时使用的路径
       public String getName()         返回文件的名称,带后缀
       public long lastModified()      返回文件的最后修改时间(时间毫秒值)
        */
        //1.length
        /*
        细节1:这个方法只能获取文件的大小(字节数量)
        如果要得到M或者G 需要不断除以1024
        细节2:这个方法无法获取文件夹的大小(文件夹调用该方法可能返回0或4096这和系统有关)
        //如果要获取一个文件夹的大小,需要这个文件夹里面的所有文件的大小累加在一起
         */
        File f1 = new File("D:\\QQLicense.rtf");//删除复制时的无关字符
        final long len1 = f1.length();
        System.out.println(len1);//253626
        //当我们的File表示是文件夹时
        File f2 = new File("D:\\Notepad++");
        final long len2 = f2.length();
        System.out.println(len2);//4096(这个答案并不正确)
        System.out.println("-------------------------------------------------");
        //2.返回文件的绝对路径getAbsolutePath()
        File f3 = new File("D:\\Notepad++");//我们以绝对路径创建的对象
        System.out.println(f3.getAbsoluteFile());//D:\Notepad++ 返回绝对路径
        File f4 = new File("small\\aa.txt");//以相对路径定义
        System.out.println(f4.getAbsoluteFile());//D:\ideaprojects\small\small\aa.txt(依然返回的是绝对路径)
        //3.getPath() 返回定义文件时使用的路径(定义时写什么将会返回什么)
        System.out.println("---------------------------------------------------------------");
        File f5 = new File("D:\\Notepad++");//用绝对路径
        System.out.println(f5.getPath());////D:\Notepad++
        File f6 = new File("small\\aa.txt");//使用相对路径
        System.out.println(f6.getPath());//small\aa.txt
        System.out.println("----------------------------------------------------------------------");
        //4.返回文件的名称getName
        //细节:当是文件调用时 将会返回文件名+拓展名
        //当是文件夹调用时,将会返回文件夹名
        File f7 = new File("D:\\QQLicense.rtf");//文件
        System.out.println(f7.getName());//QQLicense.rtf
        File f8 = new File("D:\\Notepad++");//文件夹
        System.out.println(f8.getName());//Notepad++
        System.out.println("-----------------------------------------------------------");
        //5.lastModified返回文件的最后修改时间
        File f9 = new File("D:\\QQLicense.rtf");
        final long time = f9.lastModified();
        System.out.println(time);//1664518111254



    }
}

创建和删除

package com;

import java.io.File;
import java.io.IOException;

public class FileDimo1 {
    public static void main(String[] args) throws IOException {
      /*
      public boolean createNewFile()    创建一个新的空的文件
      public boolean mkdir()            创建单级文件夹
      public boolean mkdirs()           创建多级文件夹
      public booean delete()           删除文件.空文件夹
       */
        //1.createNewFile创建一个新的文件
        /*
        细节1:如果当前路径下创建的文件不存在则创建成功 方法返回true
              如果当前路径下表示的文件存在则创建失败,方法返回false
        细节2:如果父类路径是不存在的 方法将会抛出IOEXception
         细节3:createNewFile方法创建的一定是文件 如果路径中的文件不含拓展名则创建的是不含拓展名的文件(和相同名称的文件不同)
         */
        /*File f1 = new File("C:\\Data\\AAA");//定义一个文件
        final boolean b = f1.createNewFile();//该处可能抛出异常
        System.out.println(b);//第一次创建成功将返回true 再次创建将返回false*/
        System.out.println("----------------------------------------------------------");
      //2.mkdir make Directory 创建单级文件夹
        /*
        细节1:windows当中的路径是唯一的,如果当前的路径已经存在,则创建失败,返回false
        细节2:mkdir方法只能创建单级文件夹,无法创建多级文件夹
         */
       /* File f2 = new File("C:\\Data\\AAA");
        final boolean c = f2.mkdir();
        System.out.println(c);//此时AAA.txt和创建出来的文件夹路径相同
        File f3 = new File("C:\\Data\\AAA\\AAA\\BBB");
        final boolean d = f3.mkdir();//false
        System.out.println(d);*/
        System.out.println("-----------------------------------------------------------------");
        //3.mkdirs
        //细节:既可以创建单级文件夹又可以创建多级文件夹
       /* File f5 = new File("C:\\Data\\bbb\\AAA\\BBB");//创建多级文件夹
        System.out.println(f5.mkdirs());//true
        File f6 = new File("C://Data\\ddd");//创建单级文件夹
        System.out.println(f6.mkdirs());//true*/
        //4.delete()    删除文件 文件夹


    }
}

删除

package com;

import java.io.File;

public class FileDemo2 {
    public static void main(String[] args) {
        //public boolean delete()  删除文件 文件夹
        /*
        细节:如果删除的文件 则直接删除 不走回收站
        如果删除的是文件夹:
        如果是文件夹里面是空的 则直接删除 不走回收站
        如果文件夹里面有内容 则无法删除
         */
        //删除文件
        File f1 = new File("C:\\Data\\AAA.txt");
        System.out.println(f1.delete());//删除成功
        //删除空文件夹
        File f2 = new File("C:\\Data\\ddd");
        System.out.println(f2.delete());//true
        //删除有内容的文件夹
        File f3 = new File("C::\\Data\\bbb");
        System.out.println(f3.delete());//false 删除失败
    }
}

获取并遍历

获取当前路径下的所有内容并放到一个数组中

package com;

import java.io.File;

public class FileDemo2 {
    public static void main(String[] args) {
       //public File[] listFiles()  获取当前路径下所有的内容
        //1.创建File对象
        File f = new File("C:\\Data\\bbb");
        //2.调用listFilses方法 获取当前路径下所有的内容并放在数组中
        File[] files = f.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
        //如果当前路径下是文件则当前路径下没有内容 数组内容为空 增强for循环将会出现空指针异常
    }
}

重点掌握:listFile方法的注意事项


重点掌握listFile其他的了解即可

package com;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;

public class FileDemo2 {
    public static void main(String[] args) {
       /*
       public static File[] listRoots()     列出可用的文件系统根
       public String [] list()              获取当前该路径下的所有内容
       public String [] list(FilenameFilter filter) 利用文件名过滤器获取当前该路径下的所有内容
       (掌握)public File[] listFiles()               获取当前该路径下的所有内容
       public File[] listFiles(FileFilter filter)利用文件名过滤器获取当前该路径下的所有内容
       public File[] listFiles(FilenameFilter filter)利用文件名过滤器获取当前该路径下的所有内容
        */
        //1.listRoots 获取系统中所有的盘符
       // final File[] arr = File.listRoots();
        //System.out.println(Arrays.toString(arr));//[C:\, D:\]
        //2.list 获取当前该路径下所有内容(仅仅能获取名字,无法获取具体路径)
      /*  File f1 = new File("C:\\Data\\bbb");
        final String[] arr2 = f1.list();
        System.out.println(Arrays.toString(arr2));//[AAA, addd.txt, cwd]*/
        //3.list(FilenameFilter filter)利用文件名过滤器获取当前该路径下所有内容
        //需求:获取C:\\Data\\bbb文件夹里面所有的txt文件
        /*
        accept方法的形参,以此表示bbb文件夹中每一个文件或文件夹的路径
        list的参数为一个函数式接口
        参数一:父级路径
        参数二:子级路径
        返回值:如果返回值为true,就表示当前路径保留
                如果返回值为false,则表示当前路径舍弃不要

         */
        File f3 = new File("C:\\Data\\bbb");
      String[]arr3 =  f3.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {//分别表示父级路径和子级路径
                File src = new File(dir,name);
                if(src.isFile()&&name.endsWith("txt"))
                    return true;else {
                    return false;
                }

            }
        });
        System.out.println(Arrays.toString(arr3));//[addd.txt]


    }
}

package com;

import java.io.File;
import java.util.Arrays;

public class FIleDemo3 {
    public static void main(String[] args) {
        /*
        掌握)public File[] listFiles()               获取当前该路径下的所有内容
       public File[] listFiles(FileFilter filter)利用文件名过滤器获取当前该路径下的所有内容
       public File[] listFiles(FilenameFilter filter)利用文件名过滤器获取当前该路径下的所有内容
         */
        //用listFiles获取txt文件
        File f1 = new File("C:\\Data\\bbb");
        final File[] arr = f1.listFiles();//获取当前路径下所有的内容
        for (File file : arr) {
            final String name = file.getName();//获取每一个文件或文件夹名
            if(file.isFile()&&name.endsWith("txt")){
                System.out.println(file);//C:\Data\bbb\addd.txt
                
            }

        }


    }
}

后面的2个方法的参数都是函数式接口,并这2个方法实现过滤出txt文件和前面的一样

综合练习

练习1(创建文件)

package com;

import java.io.File;
import java.io.IOException;

public class FilePractice {
    public static void main(String[] args) throws IOException {
        /*
        练习1:在C:\Data\bbb下中创建一个a.txt文件(bbb文件夹已经存在只需要创建文件)
        练习1:在模块下的bbb文件夹中创建一个a.txt文件(模块下同时没有文件夹和文件都需要创建)
         */
        //练习1
        //创建文件的路径
       /* File f = new File("C:\\Data\\bbb\\a.txt");
        //在电脑中创建文件
       boolean b = f.createNewFile();//此处要抛出异常
        System.out.println(b);//true*/
        //练习2
        //我们需要先创建文件夹再创建文件
        //定义文件夹的路径
        File f2 = new File("small\\bbb");
        final boolean b = f2.mkdirs();//创建文件夹
        System.out.println(b);
        //创建文件(可以使用子父级拼接也可以不使用)
        //定义文件路径
        File f3 = new File(f2, "a.txt");
        //创建文件
        final boolean c = f3.createNewFile();
        System.out.println(c);


    }
}

练习2(单个文件查找文件)

package com;

import java.io.File;
import java.io.IOException;

public class FilePractice {
    public static void main(String[] args) throws IOException {
       //定义一个方法找某一个文件夹中,是否有以avi结尾的电影(暂时不需要考虑子文件夹)
        File f =  new File("C:\\Data\\bbb");
        final boolean b = havaAvi(f);
        System.out.println(b);

    }
    //判断一个文件夹中是否有以avi结尾的电影
    public static boolean havaAvi(File file){
        final File[] files = file.listFiles();//得到该文件夹下所有的内容并放在数组中
        for (File file1 : files) {//file1表示该文件夹里面每一个文件和文件夹的路径
            final String name = file1.getName();//得到文件名或文件夹名
            if(name.endsWith("avi")&&file1.isFile()){
                return true;
            }
        }
        return false;
    }
}

练习3(遍历硬盘查找文件)

在所有的盘符中进行查找,难点在于各个文件夹包含的内容不统一,以至于代码无法统一编写

使用递归来解决
当引用数据类型指向null时,然后又使用该引用调用其堆空间的内容时,将会出现空指针异常
数组也是引用数据类型,可以用类来理解,int [] a ={}和int [] a = null意义不同,前者的有地址但是堆空间没有内容,后者则完全没有地址,用null调用堆空间内容将会出现空指针异常

package com;

import java.io.File;
import java.io.IOException;

public class FilePractice {
    public static void main(String[] args)  {
      //找到电脑中所有以avi结尾的电影(需要考虑子文件夹)
        //递归思想:把大问题拆分,拆到一个文件夹中不包含其他文件夹为止
        /*
        套路:
        1.进入文件夹
        2.遍历数组
        3.判断
        4.判断
         */

        findAvi();



    }
    //该方法用于电脑上所有的盘符
    public static void findAvi(){
        final File[] files = File.listRoots();//获取电脑上所有的盘符
        //遍历盘符
        for (File file : files) {
            findAvi(file);
        }
    }

    //仅仅遍历c盘
    public static void findAvi(File src){//假设传入c盘
        //1.进入文件夹
        File[] files = src.listFiles();//获取C盘下每一个文件或文件夹
        //2.遍历数组
        /*
        细节:listFiles()方法当文件夹有访问权限时将会返回空
         */
        if(files!=null){
            for (File file : files) {//数组名指向空然后使用数组名调用堆空间内容将会出现空指针异常
                //3.判断如果是文件执行具体业务逻辑
                if(file.isFile()){
                    String name = file.getName();//获取文件名
                    if(name.endsWith("avi")){
                        System.out.println(file);
                    }
                }else {//如果不是文件则进行递归继续向下查找
                    findAvi(file);
                }
            }
        }
        }

}

练习4

package com;

import java.io.File;
import java.io.IOException;

public class FilePractice {
    public static void main(String[] args)  {
        /*
        删除一个多级文件夹(文件夹里面有内容)
        delete方法只能删除文件或者空文件夹
       1.先删除文件夹里面的内容
       2.然后删除自己
         */
        File file = new File("C:\\Data");
        remove(file);
    }
    /*
    作用:删除bbb文件夹
    参数:要删除的文件夹
     */
    public static void remove(File file){

        final File[] files = file.listFiles();//得到文件夹里面所有内容
        if(files!=null){
            for (File file1 : files) {
                if(file1.isFile()){
                    file1.delete();
                }else {
                    remove(file1);

                }
            }

             file.delete();


        }

    }

}

练习5(统计文件夹的大小)

package com;

import java.io.File;
import java.io.IOException;

public class FilePractice {
    public static void main(String[] args)  {
      //统计一个文件夹的总大小
        File file = new File("C:\\Data");
        System.out.println(getLen(file));
    }
    /*
    文件夹总大小:文件夹里面所有文件的总大小
    形参表示要统计的文件夹
     */
        public static long getLen(File src){
            //1.进入文件夹
            long len = 0;//用于统计总大小(单位字节)
            final File[] files = src.listFiles();
            //2.遍历数组
            for (File file : files) {
                if(file.isFile()){
                    final long length = file.length();//获取文件的大小
             
                    len = len + length;
                    /*
                    对于len= len+length的细节:
                    len为一个函数里面的局部变量
                    当递归再次调用函数的时候 递归函数的len和没有递归的len不是同一个len
                    所有返回的len仅仅是src文件夹里面的文件总大小
                     */
                }else {
                    //如果是文件夹则进行递归处理
                    //修改前:getLen(file)
                   len = len + getLen(file);//修改后
                    //如果递归把文件夹文件总和返回并和以前的总和一个累加
                }
            }
            return len;
        }
}

练习6(统计各种文件夹的数量)(有点难度要使用Map集合)

package com;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class FilePractice {
    public static void main(String[] args) {
        //统计一个文件夹中每种文件的个数并打印(考虑子文件夹)
        /*
        打印格式如下:
        txt:3个
        doc:4个
        jpg:6个
        用到知识:File  递归  Map(用于统计)(键文件,值:数量)
        计数器思想的弊端:不知道文件夹中有多少种文件 则不知道需要设置多少个计数器变量

         */
        File file = new File("C:\\Data");
        final HashMap<String, Integer> count = getCount(file);
        System.out.println(count);

    }
    /*
        作用:统计一个文件夹中每种文件的个数
        参数:要统计的文件夹
        返回值:
        用来统计的map集合
        键:文件名  值:次数
        要考虑到的文件名:
        a.txt
        a.a.txt
        aaa(这种文件名不需要统计)

     */


    public static HashMap<String,Integer> getCount(File file){
        //1.定义集合用于统计
        HashMap<String,Integer> hm = new HashMap<>();
        //2.进入Data文件夹
        final File[] files = file.listFiles();//得到文件中所有的内容
        //3.变量数组
        for (File file1 : files) {
            if(file1.isFile()){
                //当为文件时
                final String name = file1.getName();//得到文件名
                final String[] arr = name.split("\\.");//按照点进行分割
                if(arr.length>=2){//数组长度大于等于2则需要统计
                    String endName = arr[arr.length-1];//得到最大索引上的元素即后缀名
                    if(hm.containsKey(endName)){
                        //如果该文件已经被统计
                         Integer count = hm.get(endName);//得到该文件出现的次数
                        count++;
                        hm.put(endName,count);
                    }else {
                        //该文件没有被统计过
                        hm.put(endName,1);
                    }
                }


            }else{
                //当为文件夹时进行递归处理
                //sonMap里面是子文件夹中每一种文件的个数
              HashMap<String, Integer> sonMap = getCount(file1);
              //将sonMap中的数量同步到hm中
                //1.遍历sonMap集合把里面的值累加到hm中
                final Set<Map.Entry<String, Integer>> entries = sonMap.entrySet();//放在set中
                for (Map.Entry<String, Integer> entry : entries) {
                    final String key = entry.getKey();
                    final Integer value = entry.getValue();
                    if(hm.containsKey(key)){
                        //hm中存在该键
                       Integer count = hm.get(key);//得到hm中该键的值
                        count = count +value;//将该键的值累加
                        hm.put(key,count);//将hm中这对键和值更新
                    }else {
                        //hm中不存在该键
                        hm.put(key,value);//不存在直接放入
                    }

                }

            }
        }
        return hm;
    }
}

posted @ 2023-02-04 10:01  一往而深,  阅读(367)  评论(0编辑  收藏  举报