I/O流

Java对数据的操作是通过流的方式,IO流用来处理设备之间的数据传输,上传文件和下载文件,Java用于操作流的对象都在IO包中。 而流是一组有序,有起点和有终点的数据序列,其本质就是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

作用:为数据源和目的地建立一个输送通道。

File类

IO流操作中大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件。

概述

java.io.File 类是文件和目录路径名的抽象表示。File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹,主要可以用于文件和目录的创建、查找和删除等操作。

注意: File表示的是文件和目录信息,而不表示文件的内容。

构造方法

public File(String pathname) {} //文件的绝对路径

public File(String parent, String child) {}//指定父文件绝对路径、子文件绝对路径

public File(File parent, String child) {}//指定父文件、子文件相对路径

public File(URI uri) {} //文件的URI地址

//下面这两个是File类中私有的构造函数,外面不能调用
private File(String pathname, int prefixLength) {}

private File(String child, File parent) {}public File(String pathname) {}

可以看到,File类的构造函数有6个:4个公共构造函数,2个私有构造函数。

而常用的构造方法有:

  • public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
  • public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
  • public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

看下代码演示:

//public File(String pathname)// 文件路径名
String pathName = "E:\\aaa.txt";
File file = new File(pathName);

//public File(String parent, String child) 通过父路径和子路径字符串
String parent = "E:\\aaa";
String child = "bbb.txt";
File file2 = new File(parent, child);

// public File(File parent, String child) 通过父级File对象和子路径字符串
File parentDir = new File("E:\\aaa");
String child2 = "bbb.txt";
File file3 = new File(parentDir, child2);

注意:不知道大家有没有注意到我写文件路径名是这样的"E:\\aaa" ,可是我们文件路径不是"E:\aaa" 这样吗?

因为在字符串中\是转义字符,如果你只是一个\,会认为你这个是转义字符,所以需要两个。

贴士:

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

File的常用方法

以下的需要文件是基于这个a.txt

1. 获取功能

  • public String getAbsolutePath() : 返回此File的绝对路径名字符串。
  • public String getPath() : 将此File转换为路径名字符串。
  • public String getName() : 返回由此File表示的文件或目录的名称。
  • public long length() : 返回由此File表示的文件的长度。
  • public long lastModified() : 获取最后一次的修改时间,毫秒值

代码演示下:

public class FileTest {
    public static void main(String[] args) {
        File file = new File("E:\\demo\\a.txt");

        //public String getAbsolutePath():获取绝对路径
        System.out.println("getAbsolutePath:" + file.getAbsolutePath());//getAbsolutePath:E:\demo\a.txt

        //public String getPath():获取相对路径
        System.out.println("getPath:" + file.getPath());//getPath:E:\demo\a.txt

        //public String getName():获取名称
        System.out.println("getName:" + file.getName());//getName:a.txt

        //public long length():获取长度。字节数
        System.out.println("length:" + file.length());//length:20

        //public long lastModified():获取最后一次的修改时间,毫秒值
        System.out.println("lastModified:" + file.lastModified());//lastModified:1606645407343

        //转换下格式毫秒值。
        Date time = new Date(file.lastModified());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String s = sdf.format(time);
        System.out.println(s);//2020-11-29 18:23:27
    }
}

想必这个应该不用多讲吧,看了就会用吧,直接调用就行了。

2. 判断功能

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

像往常一样,继续来一波演示,走起:

public class FileTest2 {
    public static void main(String[] args) {
        File file = new File("E:\\demo\\a.txt");

        //public boolean isDirectory():判断是否是目录
        System.out.println("isDirectory: " + file.isDirectory());//isDirectory: false

        //public boolean isFile():判断是否是文件
        System.out.println("isFile: " + file.isFile());//isFile: true

        //public boolean exists():判断是否存在
        System.out.println("exists: " + file.exists());//exists: true

        //public boolean canRead():判断是否可读
        System.out.println("canRead: " + file.canRead());//canRead: true

        //public boolean canWrite():判断是否可写
        System.out.println("canWrite: " + file.canWrite());//canWrite: true

        //public boolean isHidden():判断是否隐藏
        System.out.println("isHidden: " + file.isHidden());//isHidden: false
    }
}

不多说,看代码!看了就懂了!

3. 创建功能

  • public boolean createNewFile(): 创建文件 如果存在这样的文件,就不创建了
  • public boolean mkdir() :创建文件夹 如果存在这样的文件夹,就不创建了
  • public boolean mkdirs() : 创建文件夹,如果父文件夹不存在,会帮你创建出来

先看下创建前的文件信息:

然后像往常一样,继续来一波演示,走起:

public class FileTest3 {
    public static void main(String[] args) throws IOException {
        //public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了
        // 在e盘文件夹demo下创建一个文件夹hello
        File file = new File("E:\\demo\\hello"); //根据上面的文件信息看到这个hello文件夹是没有的
        System.out.println("mkdir: " + file.mkdir());
        System.out.println("再来判断下文件夹是否存在: " + file.exists());

        //public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了
        //在e盘目录demo下的文件夹hello创建一个文件hello.txt
        File file2 = new File(file,"\\hello.txt");//在上面已经创建了hello文件夹
        System.out.println("createNewFile: " + file2.createNewFile());
        System.out.println("再来判断下文件是否存在: " + file2.exists());

        //public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来
        File file3 = new File("E:\\demo\\world\\world");//能不能两级文件夹直接创建出来呢
        System.out.println("mkdirs: " + file3.mkdirs());
        System.out.println("再来判断下文件夹是否存在: " + file3.exists());
    }
}

第一次执行结果可以看到:

mkdir: true
再来判断下文件夹是否存在: true
createNewFile: true
再来判断下文件是否存在: true
mkdirs: true
再来判断下文件夹是否存在: true

而现在是不是文件或者文件夹都创建出来了,我们再运行一次会怎样呢?

mkdir: false
再来判断下文件夹是否存在: true
createNewFile: false
再来判断下文件是否存在: true
mkdirs: false
再来判断下文件是否存在: true

方法调用上都为false,代表了如果有文件或者有文件夹了就都不再创建了。

提一个小问题,在创建的方法中哪个有可能会抛出异常的呢? 看下代码,觉得那个可能会出错呢

File file4 = new File("E:\\world\\world2"); 
System.out.println("mkdir: " + file4.mkdir());

File file5 = new File("E:\\world\\world2");
System.out.println("mkdirs: " + file5.mkdirs());

File file6 = new File("E:\\helloWorld\\helloWorld2"); 
System.out.println("createNewFile: " + file6.createNewFile());
复制代码

运行结果可以看到:

mkdir: false
mkdirs: true
Exception in thread "main" java.io.IOException: 系统找不到指定的路径。
	at java.io.WinNTFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:1012)
	at com.it.test1.FileTest3.main(FileTest3.java:33) 

小结:

  1. mkdir如果在存在文件夹或者上级目录不存在,则会返回false即不创建,否则创建。
  2. mkdirs如果在存在文件夹,则会返回false即不创建,否则创建。
  3. createNewFile如果在存在文件,则会返回false即不创建,否则创建。如果上级目录不存在,则会报错,系统找不到指定的路径的IOException

4. 删除功能

现在我们再看看下现在文件夹信息:

在上面的创建过程中,我们已经有了hello文件夹及目录下的hello.txtworld文件夹下的world文件夹。

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

话不在多说,上演示:

public class FileTest4 {
	public static void main(String[] args) {
        //public boolean delete():删除由此File表示的文件或目录。
        //接下来我们来删除之前创建的文件。
        //1.我们删除掉hello文件夹下的hello.txt
        File file = new File("e:\\demo\\hello\\hello.txt");
        System.out.println("删除hello.txt:" + file.delete());

        //2. 接下来我再删一次呢?会返回什么呢?
        System.out.println("删除hello.txt:" + file.delete());

        //3. 接下来我还想删除掉hello文件夹。
        File file2 = new File("e:\\demo\\hello");
        System.out.println("删除hello文件夹:" + file2.delete());

        //4. 接下来我想直接删除掉demo下的world文件夹。我们知道里面还有world文件夹,那会发生什么呢?
        File file3 = new File("e:\\demo\\world");
        System.out.println("删除world文件夹:" + file3.delete());
    }
}

我们猜测下最后删除world文件夹成功吗?

运行程序结果:

删除hello.txt:true
删除hello.txt:false
删除hello文件夹:true
删除world文件夹:false

注意:

  1. 可以看到如果我们删除hello.txt了,再删除,就返回false即删除失败。

  2. 如果文件夹下还有文件或者文件夹,也会删除失败。即我们想直接删除demo下的world文件夹就会失败,因为里面还有文件夹。

  3. 像我们平时删除文件的时候,他是不是就会去到回收站呢,那我们用Java删除的时候,文件也是去了回收站吗?

    可以看到我们回收站是空的。并没有去到回收站,而是被JVM真正的删除掉了。

5. 其他功能

  1. 重命名功能

    • public boolean renameTo(File file) : 重命名
    public class FileTest5 {
        public static void main(String[] args) {
            //public boolean renameTo(File file)
            File file = new File("e:\\demo\\a.txt");
            System.out.println("renameTo: " + file.renameTo(new File("e:\\demo\\b.txt")));//renameTo: true
        }
    }

    程序运行结果:

    renameTo: true

    那我们再去看下文件信息:

  2. 绝对路径和相对路径

    • 绝对路径:从盘符开始的路径,这是一个完整的路径。如:e\\demo.a.txt

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

      public class FileTest6 {
          public static void main(String[] args) {
              // E盘下的bbb.java文件
              File f = new File("E:\\bbb.java");
              System.out.println(f.getAbsolutePath());
      
              // 项目下的bbb.java文件
              File f2 = new File("bbb.java");
              System.out.println(f2.getAbsolutePath());
          }
      }

      运行结果如下:

      E:\bbb.java
      E:\IdeaWorkSpace\project_File\bbb.java
  3. 目录的遍历

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

    一样继续演示吧:

    public class FileTest7 {
        public static void main(String[] args) {
            File dir = new File("e:\\demo");
            //public String[] list():返回一个String数组,表示该File目录中的所有子文件或目录。
            //获取当前目录下的文件以及文件夹的名称。
            String[] names = dir.list();
            for(String name : names){
                System.out.println(name);
            }
    
            //public File[] listFiles():返回一个File数组,表示该File目录中的所有的子文件或目录。
            //获取当前目录下的文件以及文件夹对象,只要拿到了文件对象,那么就可以获取更多信息
            File[] files = dir.listFiles();
            for (File file : files) {
                System.out.println(file);
            }
        }
    }

    程序运行结果:

    aaa
    b.txt
    bbb
    e:\demo\aaa
    e:\demo\b.txt
    e:\demo\bbb

    注意:调用listFiles方法的File对象,表示的必须是实际存在的目录,否则返回null,无法进行遍历。

6. 小结File

  1. File可以用于表示文件和目录的信息,但是它不表示文件的内容。在后续的IO流操作中就可以对文件进行读写的操作啦。
  2. 无论该路径下是否存在文件或者目录,都不影响File对象的创建。虽然创建File对象没问题,可能后续操作对File对象的引用可能导致报错。
  3. 常用的方法介绍也在上面一一结束了,这里倒是没什么必要再写一遍了,嘿嘿!

总结

相信各位看官都对IO流中File类有了一定了解,期待等待窥探IO流教学吧!

当然还有很多流等着下次一起看吧!欢迎期待下一章的到来!

学到这里,今天的世界打烊了,晚安!虽然这篇文章完结了,但是我还在,永不完结。我会努力保持写文章。来日方长,何惧车遥马慢!

感谢各位看到这里!愿你韶华不负,青春无悔!

注: 如果文章有任何错误和建议,请各位大佬尽情留言!如果这篇文章对你也有所帮助,希望可爱亲切的您给个 <stron>下呗,非常感谢啦!</stron>


作者:***爷哪吒
链接:https://juejin.cn/post/6992508053232828424
来源:掘金