Java IO之File类的使用

File类的理解

  • File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)。
  • File类声明在java.io包下:文件和文件路径的抽象表示形式,与平台无关。
  • File类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO流来完成。
  • 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。
  • 后续File类的对象常会作为参数传递到流的构造器中,指明读取或写入的”终点“。

File类的实例化

常用构造器

File(String filePath)
File(String parentPath,String childPath)
File(File parentFile,String childPath)

代码示例:

public class FileTest {

    @Test
    public void test1() {
        // 现在的 file 还只是内存、对象层面的,硬盘中并没有这个文件
        // 构造器1
        File file1 = new File("hello.txt");
        File file2 = new File("D:\\code\\JavaSE\\src\\javase\\io\\file\\hello.txt");
        System.out.println(file1);
        System.out.println(file2);

        // 构造器2
        File file3 = new File("D:\\code\\JavaSE\\src\\javase\\io\\file", "hello");
        System.out.println(file3);

        // 构造器3
        File file4 = new File(file3, "hello3.txt");
        System.out.println(file4);
    }
}

路径分类

  • 相对路径:相较于某个路径下,指明的路径
  • 绝对路径:包含盘符在内的文件或文件目录的路径。

说明:

  • IDEA中:
    • 如果使用JUnit中的单元测试方法测试,相对路径即为当前Module下。
    • 如果使用main()测试,相对路径即为当前的Project下。
  • Eclipse中:
    • 不管使用单元测试方法还是使用main()测试,相对路径都是当前的Project下。

路径分隔符

  • Windows和DOS系统默认使用\来表示
  • UNIX和URL使用/来表示
  • Java程序支持跨平台运行,因此路径分隔符要慎用。
  • 为了解决这个隐患,File类提供了一个常量: public static final String separator。根据操作系统,动态的提供分隔符。

举例:

//Windows和DOS系统 使用 “/”其实也是可以的
File file1 = new File("E:\\io\\test.txt");
//UNIX和URL
File file = new File("E:/io/test.txt");
//java提供的常量
File file = new File("E:"+File.separator+"io"+File.separator+"test.txt");

File类的常用方法

File类的获取功能

  • public String getAbsolutePath():获取绝对路径
  • public String getPath() :获取路径
  • public String getName() :获取名称
  • public String getParent():获取上层文件目录路径。若无,返回null
  • public long length():获取文件长度(即:字节数)。不能获取目录的长度。
  • public long lastModified():获取最后一次的修改时间,毫秒值

如下的两个方法适用于文件目录:

  • public String[] list():获取指定目录下的所有文件或者文件目录的名称数组
  • public File[] listFiles():获取指定目录下的所有文件或者文件目录的File数组

代码示例:

@Test
public void test2() {
    File file1 = new File("hello.txt");
    File file2 = new File("D:\\io\\hi.txt");

    System.out.println(file1.getAbsolutePath());
    System.out.println(file1.getPath());
    System.out.println(file1.getAbsolutePath());
    System.out.println(file1.getPath());
    System.out.println(file1.getName());
    System.out.println(file1.getParent());
    System.out.println(file1.length());
    System.out.println(new Date(file1.lastModified()));

    System.out.println();

    System.out.println(file2.getAbsolutePath());
    System.out.println(file2.getPath());
    System.out.println(file2.getName());
    System.out.println(file2.getParent());
    System.out.println(file2.length());
    System.out.println(file2.lastModified());
}

@Test
public void test3() {
    File file = new File("D:\\code\\JavaSE\\src\\javase");
    String[] list = file.list();
    for (String s : list) {
        System.out.println(s);
    }

    System.out.println();

    File[] files = file.listFiles();
    for (File f : files) {
        System.out.println(f);
    }
}

File类的重命名功能

  • public boolean renameTo(File dest):把文件重命名为指定的文件路径
  • 注意:file1.renameTo(file2)为例:要想保证返回true,需要file1在硬盘中是存在的,且file2不能在硬盘中存在
@Test
public void test4(){
    File file1 = new File("hello.txt");
    File file2 = new File("D:\\io\\hi.txt");

    boolean renameTo = file2.renameTo(file1);
    System.out.println(renameTo);

}

File类的判断功能

  • public boolean isDirectory():判断是否是文件目录
  • public boolean isFile() :判断是否是文件
  • public boolean exists() :判断是否存在
  • public boolean canRead() :判断是否可读
  • public boolean canWrite() :判断是否可写
  • public boolean isHidden() :判断是否隐藏

代码示例:

@Test
public void test5(){
    File file1 = new File("hello.txt");
    file1 = new File("hello1.txt");

    System.out.println(file1.isDirectory());
    System.out.println(file1.isFile());
    System.out.println(file1.exists());
    System.out.println(file1.canRead());
    System.out.println(file1.canWrite());
    System.out.println(file1.isHidden());

    System.out.println();

    File file2 = new File("d:\\io");
    file2 = new File("d:\\io1");
    System.out.println(file2.isDirectory());
    System.out.println(file2.isFile());
    System.out.println(file2.exists());
    System.out.println(file2.canRead());
    System.out.println(file2.canWrite());
    System.out.println(file2.isHidden());

}

File类的创建功能

创建硬盘中对应的文件或文件目录

  • public boolean createNewFile():创建文件。若文件存在,则不创建,返回false
  • public boolean mkdir():创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
  • public boolean mkdirs():创建文件目录。如果此文件目录存在,就不创建了。如果上层文件目录不存在,一并创建

代码示例:

@Test
public void test6() throws IOException {
    File file1 = new File("hi.txt");
    if (!file1.exists()) {
        // 文件的创建
        file1.createNewFile();
        System.out.println("创建成功");
    } else {
        file1.delete();
        System.out.println("删除成功");
    }
}

@Test
public void test7() {
    // 文件目录的创建
    File file1 = new File("D:\\io1\\io2\\io3");
    boolean mkdir = file1.mkdir();
    if (mkdir) {
        System.out.println("创建成功1");
    }

    File file2 = new File("D:\\io1\\io2\\io4");
    boolean mkdir1 = file2.mkdirs();

    if (mkdir1) {
        System.out.println("创建成功2");
    }

    // 要想删除成功,io4文件目录下不能有子目录或文件
    File file3 = new File("D:\\io1\\io2\\io4");

    System.out.println(file3.delete());
}

File类的删除功能

删除磁盘中的文件或文件目录。

public boolean delete():删除文件或者文件夹(不能有文件或者子文件夹)。

删除注意事项:Java中的删除不走回收站。

内存解析

内存解析

小练习

利用File构造器,new一个文件目录file。要求:在其中创建多个文件和目录,编写方法,实现删除file中指定文件的功能。

public class FileTest2 {

    @Test
    public void test() throws IOException {
        File file = new File("D:\\io\\io1");    //先创建文件夹
        if (!file.exists()) {
            file.mkdirs();
        }
        File haha = new File("D:\\io\\io1\\haha.txt");
        // 创建一个与haha同目录下的另外一个文件,文件名为:xixi.txt
        File xixi = new File(haha.getParent(), "xixi.txt");
        // 如果 D:\io\io1 这个路径不存在,就会报错java.io.IOException: 系统找不到指定的路径。
        boolean newFile = xixi.createNewFile();
        if (newFile) {
            System.out.println("创建成功!");
        }else {
            System.out.println("文件已存在!");
        }

        // 删除xixi.txt
//        boolean flag = deleteFile(xixi);
//        if (flag) {
//            System.out.println("文件删除成功!");
//        } else {
//            System.out.println("文件不存在!");
//        }
    }

    public boolean deleteFile(File file) {
        if (file.exists()) {
            return file.delete();
        } else {
            return false;
        }
    }
}

判断指定目录下是否有后缀名为.jpg的文件,如果有,就输出该文件名称。

public class FindJPGFileTest {

    @Test
    public void test1() {
        File src = new File("D:\\io\\io1");
        String[] fileNames = src.list();
        if (fileNames.length == 0) {
            System.out.println("没有找到.jpg图片!");
        } else {
            for (String fileName : fileNames) {
                if (fileName.endsWith(".jpg")) {
                    System.out.println(fileName);
                }
            }
        }

    }

    @Test
    public void test2() {
        File srcFile = new File("D:\\io\\io1");
        File[] listFiles = srcFile.listFiles();
        if (listFiles.length == 0) {
            System.out.println("没有找到.jpg文件!");
        } else {
            for (File file : listFiles) {
                if (file.getName().endsWith(".jpg")) {
                    System.out.println(file.getAbsolutePath());
                }
            }
        }

    }
    /**
     *  File 类提供了文件过滤器方法
     *  public String[] list(FilenameFilter filter)
     *  public File[] listFiles(FileFilter filter)
     *  public File[] listFiles(FilenameFilter filter)
     * */

    @Test
    public void test3() {
        File srcFile = new File("D:\\io\\io1");
        File[] listFiles = srcFile.listFiles((dir, name) -> name.endsWith(".jpg"));
//        File[] listFiles = srcFile.listFiles(new FilenameFilter() {
//            @Override
//            public boolean accept(File dir, String name) {
//                return name.endsWith(".jpg");
//            }
//        });
        if (listFiles.length == 0) {
            System.out.println("没有找到.jpg文件!");
        } else {
            for (File file : listFiles) {
                System.out.println(file.getAbsolutePath());
            }
        }

    }
}

遍历指定目录所有文件名称,包括子文件目录中的文件。拓展1:计算指定目录占用空间的大小。拓展2:删除指定文件目录及其下的所有文件。

public class ListFileTest {

    @Test
    public void test1() {

        // 1. 创建目录对象,请确保路径是存在的
        File file = new File("D:\\io");

        // 2. 使用递归遍历指定目录下的所有文件及文件夹(包含自身)
        printSubFile(file);
        // 计算指定目录占用空间大小
        System.out.println(getDirectorySize(file));
        // 使用递归删除指定文件目录及其下的所有文件
        deleteDirectory(file);
    }

    /**
     * 使用递归遍历指定目录下的所有文件和文件夹(包括目录自身)
     * @param dir
     */
    public void printSubFile(File dir) {
        System.out.println(dir.getAbsolutePath());
        File[] files = dir.listFiles();
        if (files.length != 0) {
            for (File f : files) {
                if (f.isDirectory()) {  // 如果是文件夹,则递归调用自身
                    printSubFile(f);
                } else {
                    System.out.println(f.getAbsolutePath()); // 输出文件绝对路径
                }
            }
        }


    }

    /**
     * 拓展1:求指定目录所占用空间的大小
      */
    public long getDirectorySize(File file) {
        // file是文件,那么直接返回file.length()
        // file是目录,把它的下一级目录的所有文件大小加起来就是它的总大小
        long size = 0;
        if (file.isFile()) {
            size += file.length();
        } else {
            File[] files = file.listFiles(); // 获取当前文件夹下的文件或文件夹
            for (File f : files) {
                size += getDirectorySize(f);
            }
        }
        return size;
    }

    /**
     * 拓展2:删除指定的目录(包含目录中的子目录及文件)
     */
    public void deleteDirectory(File file) {
        // 如果file是文件,直接delete
        // 如果file是目录,先把它的子目录以及文件删除,然后删除自己
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files.length != 0) { // 如果 length == 0;说明是最后一个文件夹,并且是空的
                for (File f : files) {
                    deleteDirectory(f); // 递归调用
                }
            }
            file.delete(); // 删除空文件夹
        }
        file.delete(); // 删除文件
    }

}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容