Java中的File类

1.1.0、学习目的

  • 理解 File 类的作用和意义
    • 参见 1.1.1 概述部分
  • 理解 File 类中的常量的含义和作用
    • 参见 1.1.2 常量部分
  • 掌握通过构造方法创建 File 实例
    • 参见 1.1.3 构造方法 部分
  • 掌握 File 类中的实例方法
    • 参见 1.1.4 实例方法部分
  • 了解 File 类中的类方法
    • 参见 1.1.5 类方法 部分
  • 理解文件过滤并掌握过滤文件的方法
    • 参见 1.1.6 文件过滤 部分
  • 理解文件系统中的相对路径和绝对路径
    • 参见 1.1.4.11 绝对路径 部分
  • 理解文件或目录的元数据
    • 参见 1.1.4.13 获取权限 部分

1.1.1、概述

File 类的实例是文件或目录的路径名的抽象表示形式。Java虚拟机中的一个File实例表示一个路径名 。

比如,磁盘上 D:/malajava 目录名称为 阿凡达.mp4 的视频文件,它与JVMFile实例的关系如下图所示:

Java中的File类_第1张图片
file-instance.png

千万不要被 File 这个名称所误导:

  • 一个File实例所表示的路径可能是个一个文件,也可能是一个目录。

  • 一个File实例所表示的路径名可能在磁盘上是存在的,也可能在磁盘上根本就不存在;

另外,File类提供了用于操作文件或目录的方法,但并不支持访问文件的内容。

访问文件中的内容,需要通过文件输入流来实现,访问文件内容请参见后续内容。

1.1.2、常量

File 类提供了 4 个表示分隔符的常量:

Java中的File类_第2张图片
file-constant.png

不同的系统平台下,这四个常量的取值也不相同

  • 在Windows 平台下

    • pathSeparator 和 pathSeparatorChar 对应的是 ;
    • separator 和 separatorChar 对应的是 \
  • Unix / Linux / OS X 平台下

    • pathSeparator 和 pathSeparatorChar 对应的是 :
    • separator 和 separatorChar 对应的是 /

这里需要注意:

separator 和 separatorChar 表示的是文件系统中路径的不同部分之间的分隔符,比如:

  • D:/malajava/阿凡达.mp4

而 pathSeparator 和 pathSeparatorChar 则表示环境变量中 Path 变量值中不同部分的分隔符,比如:

  • %JAVA_HOME%\bin;D:\databases\mysql-8.0.15-winx64\bin

1.1.3、构造方法

File 类提供了 4 个构造方法用于创建File实例:

Java中的File类_第3张图片
file-constructor.png

举例:

File first = new File( "D:/malajava/阿凡达.mp4" );
System.out.println( first ); // D:/malajava/阿凡达.mp4

File second = new File( "D:/malajava" , "阿凡达.mp4" );
System.out.println( second ); // D:/malajava/阿凡达.mp4

File third =  new File( "D:/malajava" );
System.out.println( third ); // D:/malajava

File fourth = new File( third , "阿凡达.mp4" );
System.out.println( fourth ); // D:/malajava/阿凡达.mp4

因为绝大多数朋友不熟悉 java.net.URI,所以不研究 public File ( URI uri )

注意,File类重写了从Object类继承的toString方法,因此:

System.out.println( fourth );

形式的输出语句,等同于:

System.out.println( fourth.toString() );

File实例是一个文件路径或目录路径的抽象表示形式,这个路径可能在磁盘上并不存在,

因此还需要通过exists方法来加以判断(exists方法在后面讲解)。

1.1.4、实例方法

1.1.4.1、判断是否存在

File类中的exists方法用于判断File实例所表示的路径名是否在磁盘上存在:

public boolean exists() 

当File实例所表示的路径名在磁盘上存在时返回 true,否则返回false

举例:

File fod = new File( "C:/Users" );
System.out.println( fod.exists() ) ; // true

这里之所以将 File 类型的引用变量命名为 fod,是因为不能确定该变量所指向的File实例表示的是文件还是目录,因此使用了 file or directory 三个单词的首字母,后文中凡是出现 fodfile or directory之意。

1.1.4.2、判断是否文件

File类中的isFile方法用于判断File实例所表示的路径名是否是个文件:

public boolean isFile()

当File实例所表示的路径在磁盘上存在并且是个文件时返回 true,否则返回false

举例:

File fod = new File( "C:/Users" );
System.out.println( fod.exists() ) ; // true
System.out.println( fod.isFile() ) ; // false

1.1.4.3、判断是否目录

File类中的isDirectory方法用于判断File实例所表示的路径名是否是个目录:

public boolean isDirectory()

当File实例所表示的路径名在磁盘上存在并且是个目录时返回 true,否则返回false

举例:

File fod = new File( "C:/Users" );
System.out.println( fod.exists() ) ; // true
System.out.println( fod.isDirectory() ) ; // true

1.1.4.4、判断是否是隐藏文件

File类中的isHidden方法用于判断File实例所表示的路径名是否是隐藏目录或隐藏文件:

public boolean isHidden() 

当File实例所表示的路径名是个隐藏目录或隐藏文件时返回 true,否则返回false

举例:

File fod = new File( "C:/Users" );
System.out.println( fod.exists() ) ; // true
System.out.println( fod.isHidden() ) ; // false

1.1.4.5、判断是否是绝对路径

File类中的isAbsolute方法用于判断File实例所表示的路径名是否是绝对路径:

public boolean isAbsolute()

当File实例所表示的路径名是绝对路径时返回 true,否则返回false

举例:

File fod = new File( "C:/Users" );
System.out.println( fod.isAbsolute() ) ; // true

1.1.4.6、获取路径及名称

File类提供了获取File实例所表示路径名对应的目录或文件的名称:

public String getName()

同时也提供了获取File实例所表示路径的方法(以字符串形式返回):

public String getPath()

举例:

File fod = new File( "D:/malajava/阿凡达.mp4" );

String name = fod.getName();
System.out.println( name ); // 阿凡达.mp4

String path = fod.getPath();
System.out.println( name ); // D:/malajava/阿凡达.mp4

1.1.4.7、获取访问时间

File类提供了获取文件或目录最后修改时间(以毫秒计)的方法:

public long lastModified()

举例:

File fod = new File( "D:/malajava/阿凡达.mp4" );
long time = fod.lastModified();
System.out.println( time );

Date date = new Date( time ); // 根据毫秒值构建Date实例
DateFormat df = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS" ); // 创建日期格式化器
String s = df.format( date ); // 将日期格式化
System.out.println( s );

1.1.4.8、获取文件长度

当 File 实例所表示的路径名在磁盘上存在,并且是个文件时,可以通过 length 方法来获取文件的长度(体积):

public long length()

该方法所返回的文件长度以字节为单位。

如果File实例所表示的路径名是一个目录,则返回值是不确定的。

如果File实例所表示的路径名在磁盘上是不存在,则返回 0L

举例:

File fod = new File( "D:/malajava/hello.txt" ); // 请保证该文件在磁盘上是存在的
if( fod.exists() && fod.isFile() ) {
  long size = fod.length();
  System.out.println( size + " bytes.")
}

1.1.4.9、获取项目列表

File类提供了获取指定目录中所包含的子目录和文件列表的方法:

  • 获取File实例所表示路径名对应的目录中所有子目录名称及文件名称组成的数组
public String[]  list()

举例:

File fod = new File( "D:/malajava" );
if( fod.exists() && fod.isDirectory() ) {
  // 获取 fod 所表示的目录内所有目录名称及文件名称对应的数组
  String[] names = fod.list();
  for( int i = 0 ; i < names.length ; i++ ){
    String name = names[ i ] ;
    System.out.println( name ); // 输出单个目录或单个文件的名称
  }
}
  • 获取File实例所表示的目录内所有目录和文件对应的File数组
public File[]  listFiles()

举例:

File fod = new File( "D:/malajava" );
if( fod.exists() && fod.isDirectory() ) {
  // 获取 fod 所表示的目录内所有目录和文件对应的File数组
  File[] fods = fod.listFiles();
  for( int i = 0 ; i < fods.length ; i++ ){
    File fd = fods[ i ] ; // 获取 单个目录或单个文件 对应的 File 实例
    String name = fd.getName(); // 获取文件名称或目录名称
    System.out.println( name + " 是个 " + ( fd.isDirectory() ? "目录" : "文件" ) );
  }
}

1.1.4.10、获取父路径

File类提供了用于获取File实例所表示路径名的上级路径的方法:

  • 以字符串形式返回当前路径的上一级路径
public String getParent()

举例:

File fod = new File( "D:/malajava/阿凡达.mp4" ); 
System.out.println( fod ); // D:/malajava/阿凡达.mp4

String parent = fod.getParent();
System.out.println( parent ); // D:/malajava
  • 获取当前路径名的上一级路径对应的File实例
public File getParentFile()

举例:

File fod = new File( "D:/malajava/阿凡达.mp4" ); 
System.out.println( fod ); // D:/malajava/阿凡达.mp4

File parent = fod.getParentFile();
System.out.println( parent ); // D:/malajava

1.1.4.11、获取绝对路径

在文件系统中,文件或目录的路径可以分为相对路径和绝对路径两种情况:

  • 相对路径: 相对于当前路径来确定其它文件或目录的路径

    • 符号 . 表示当前路径
  • 当前路径的确定要看具体情况,它是灵活变动的

    • 符号 .. 表示 当前路径的父路径 ( 即上一级路径 )
  • 举例

    • ./first.txt 表示当前目录下的 first.txt 文件
      • ../second.txt 表示当前目录父目录中的 second.txt 文件
      • ../../third.txt 表示当前目录父目录的父目录中的 third.txt 文件
  • 绝对路径: 相对于根路径来确定文件或目录的路径

    • 根路径

      • 不同的操作系统中所使用的文件系统也是不相同的,它们表示根路径的方法也是不同的
    • Windows 系统中,通常将硬盘分为几个分区,每个分区相对独立,都有自己的根分区

      • 比如: C盘对应的根路径就是 C:\ ,D盘对应的根路径就是 D:\
    • Unix/Linux/macOS 系统中根路径统一为 /

    • Unix/Linux/macOS 系统下也可以有不同的分区,但所有分区都挂载在 / 路径下

    • 举例

      • C:\Users 表示 Windows 系统下 C 盘 根目录下的 Users 目录
      • /Users 表示 Unix 或 Linux 或 macOS 系统中根目录下的 Users 目录

File类提供了获取某个路径名的绝对路径的方法。

如果创建File实例时采用的是相对路径,则可以通过以下方法来获取它所对应的绝对路径:

  • 以字符串形式返回File实例所表示路径名的绝对路径
public String getAbsolutePath()

举例:

File current = new File( "." ); // 创建一个表示当前路径的File实例
System.out.println( current ); 

String absolute = current.getAbsolutePath(); // 获取当前路径的绝对路径
System.out.println( absolute ); 

注意: 一定要亲自运行代码。通过输出的结果来对比它们的区别。

  • 获取File实例所表示的相对路径对应的绝对路径并返回该绝对路径对应的File实例
public File getAbsoluteFile()

举例:

File current = new File( "." ); // 创建一个表示当前路径的File实例
System.out.println( current ); 

File absolute = current.getAbsoluteFile();
System.out.println( absolute ); 

注意,尽管举例中 currentabsolute 所指为同一个目录,但是它们在 JVM 中并不是同一个实例。

1.1.4.12、获取规范路径

File实例提供了获取指定路径名规范路径名的方法:

  • 以字符串形式返回File实例所表示路径的的规范路径名
public String getCanonicalPath() throws IOException

举例:

try {
    File fod = new File( "." ); // 创建一个表示当前路径的File实例
    String canonical = fod.getCanonicalPath(); // 获取规范化路径名
    System.out.println( canonical ); 
} catch (IOException e) {
    e.printStackTrace();
}

注意:

getCanonicalPath方法返回的规范化路径名getAbsolutePath方法返回的绝对路径是不相同的。

对比如下:

File fod = new File( "." );
System.out.println( fod.getCanonicalPath() ); // 规范化路径名
System.out.println( fod.getAbsolutePath() ); // 绝对路径

请自行处理以上代码中的 IOException异常。

  • 获取File实例所表示路径名规范形式
public File getCanonicalFile() throws IOException

举例:

try {
    File fod = new File( "." ); // 创建一个表示当前路径的File实例
    File canonicalFile = fod.getCanonicalFile(); // 获取规范化路径名对应的File实例
    System.out.println( canonicalFile ); 
} catch (IOException e) {
    e.printStackTrace();
}

注意: getCanonicalFile方法返回的File实例与getAbsoluteFile方法返回的File实例是不相同的。

对比如下:

File fod = new File( "." );
System.out.println( fod.getCanonicalFile() ); // 规范化形式
System.out.println( fod.getAbsoluteFile() ); // 绝对路径

请自行处理以上代码中的 IOException异常。

1.1.4.13、获取权限

文件中存储的内容目录中所包含的项目 不同,描述文件或目录本身的特征的系统数据被称作元数据。

文件或目录的元数据包括:

  • 文件或目录的 名称

    • File类的getName()方法用于获取文件或目录的名称
  • 文件 体积 ,也称作文件长度,即文件中所包含内容的字节数

    • 对于文件而言,可以通过File类提供的length()方法获取文件体积
  • 文件或目录的 创建时间

    • 因为设计上的缺陷,File类并没有提供获取文件或目录创建时间的方法
    • Java 7 开始提供了 java.nio.file.attribute.BasicFileAttributes 用于获取文件或目录的创建时间
  • 文件或目录的 访问时间

    • 因为设计上的缺陷,File类并没有提供获取文件或目录最后访问时间的方法
    • Java 7 开始提供了 java.nio.file.attribute.BasicFileAttributes 用于获取文件或目录的访问时间
  • 文件或目录的 修改时间

    • File类的lastModified()方法可以获取文件最后修改时间
    • Java 7 开始提供了 java.nio.file.attribute.BasicFileAttributes 用于获取文件或目录的修改时间
  • 文件或目录的权限

    • 读取权限
    • 修改权限 ( 也叫写权限 )
    • 执行权限

File类提供了获取和设置文件或目录权限的方法,这里仅列举获取权限的方法:

  • 测试应用程序是否可以读取抽象路径名表示的文件或目录
public boolean canRead()
  • 测试应用程序是否可以修改抽象路径名表示的文件或目录
public boolean canWrite()
  • 测试应用程序是否可以执行抽象路径名表示的文件
public boolean canExecute()

举例:

File f = new File( "C:/Windows/notepad.exe" );
System.out.println( f.canRead() );
System.out.println( f.canWrite() );
System.out.println( f.canExecute() );

1.1.4.14、创建目录

File类中提供了用于创建新目录的方法:

  • 在已经存在的目录中创建单个子目录
public boolean mkdir()

使用该方法创建目录时,必须保证新目录的父目录是存在的,并且当前操作系统用户对该目录拥有写权限。

举例:

File dir = new File( "D:/power" ); // 创建一个File实例表示目标目录的路径
File parent = dir.getParentFile(); // 获取被创建目标目录的父路径

// 如果 父路径 存在 且 当前操作系统用户拥有对该目录的写权限
if( parent.exists() && parent.carWrite() ) {
  boolean x = dir.mkdir();// 在 D 盘根目录下创建 power 目录
  System.out.println( x ? "创建成功" : "创建失败" );
}

这里需要注意,必须保证新创建的目录的父目录是存在的,也需要保证新创建的目录是不存在的。

  • 创建多层次的目录
public boolean mkdirs()

当被创建目录的父目录不存在时,可以通过该方法来先创建父目录后再创建子目录。

举例:

// 指定被创建的多层次目录的根目录
File root = new File( "D:/malajava" );
// 创建一个File实例,它表示新创建的目录对应的路径
File dir = new File( root , "first/second/third" );
// 如果 root 表示的目录在磁盘上存在,且当前用户(操作系统用户)拥有对该目录的写权限
if( root.exists() && root.canWrite() ){
  boolean x = dir.mkdirs();
  System.out.println( x );
}

这里,最终创建的目录是 third,但如果 second 目录不存在,则首先创建 second目录。

当然如果 first目录也不存在,也会首先创建该目录,随后才创建second目录

1.1.4.15、创建文件

File类中也提供了用于创建新文件的方法:

public boolean createNewFile() throws IOException

当当前用户(操作系统用户)拥有对指定目录的写权限时,可以通过 createNewFile 方法在该目录中创建文件。

举例:

File f = new File( "D:/malajava/hello.txt" );
File p = f.getParentFile();
if( p.exists() && p.canWrite() ) {
  boolean x = f.createNewFile(); //这里存在受检查异常(IOException),请自行处理
  System.out.println( x ? "创建成功" : "创建失败" );
}

因为File实例仅仅是一个文件或目录的抽象路径表示形式,因此这里创建的新文件都是空文件(0字节),如果需要向文件中写入内容,则需要通过文件输出流,通过文件输出流向文件输出内容请参见后续章节。

另外,通过 createNewFile 方法创建的新文件未必非要是文本文件(.txt),它可以是任意类型的文件。文件中究竟存储的是什么内容,取决于通过文件输出流向文件中输出的内容。

1.1.4.16、重命名目录或文件

File类提供了对目录或文件进行重命名的方法:

public boolean renameTo( File destination )

其中:

  • File类型的参数表示新文件名称对应的路径
  • 当且仅当重命名成功时,返回 true ;否则返回 false

举例:

File original = new File( "D:/malajava/阿凡达.mp4" );

// 判断 original 所表示的 文件或目录 是否存在
if( original.exists() ) {
    File parent = original.getParentFile(); // 获取original所表示路径的父路径

    String newName = "Avatar.mp4" ; // 指定新名称
    File destination = new File( parent , newName ); // 创建一个表示新文件名对应路径的File实例

  // 将 original 表示的文件或目录 重命名 为 destination 对应的名称
    boolean x = original.renameTo( destination );
    System.out.println( x ? "重命名成功" : "重命名失败" );
}

这里假设 D:/malajava 目录中存在 阿凡达.mp4 这个文件。

另外通过 renameTo 不仅可以为文件重命名,也可以对目录重命名,有兴趣的同学可以自己测试。

1.1.4.17、删除目录或文件

File类提供了用于删除目录或文件的方法:

  • 删除指定File实例所表示路径名对应的文件或目录
public boolean delete()

当且仅当成功删除文件或目录时,返回 true;否则返回 false

举例:

public static void main( String[] args ) throws Exception {
    File fod = new File( "D:/temp" ); // 设D盘根目录下存在temp目录
  if( fod.exists() && fod.canWrite() ) {
    System.out.println( "准备删除文件" );
    Thread.sleep( 10000 ); // 让当前线程睡眠10000毫秒(即10秒),时间一到就会立即删除相应的文件
    fod.delete();
    Thread.sleep( 50000 ); // 让当前线程睡眠50000毫秒(即50秒)
    System.out.println( "JVM即将终止" );
  }
}

在上例中,当前线程被阻塞50秒,在这50秒的时间里可以查看文件是否被删除。

  • JVM终止时再删除指定File实例所表示路径对应的文件或目录
public void deleteOnExit()

delete 方法不同,deleteOnExit 方法不是立即删除文件或目录,而是在JVM终止时才删除。

举例:

public static void main( String[] args ) throws Exception {
    File fod = new File( "D:/temp" ); // 设D盘根目录下存在temp目录
  if( fod.exists() && fod.canWrite() ) {
    System.out.println( "准备删除文件" );
    Thread.sleep( 10000 ); // 让当前线程睡眠10000毫秒(即10秒),时间一到就会立即删除相应的文件
    fod.deleteOnExit();
    Thread.sleep( 50000 ); // 让当前线程睡眠50000毫秒(即50秒)
    System.out.println( "JVM即将终止" );
  }
}

注意,如果JVM不终止,文件或目录是不会被删除的。

可以在线程睡眠期间查看文件或目录是否还存在,等到JVM终止后可以再次查看文件或目录是否存在。

1.1.4.18、获取硬盘空间

  • 获取抽象路径名所在分区的大小
public long getTotalSpace()
  • 获取抽象路径名所在分区中未分配的字节数
public long getFreeSpace()
  • 获取抽象路径名所在分区上可用于当前虚拟机的字节数
public long getUsableSpace()

举例:

File fod = new File( "D:/malajava" );
System.out.println( fod.getTotalSpace() );
System.out.println( fod.getFreeSpace() );
System.out.println( fod.getUsableSpace() );

1.1.4.19、获取字符串形式

File类重写了从Object类继承的toString方法,用于获取File实例所表示路径名的字符串形式,该字符串就是 getPath() 方法返回的字符串。

举例:

File fod = new File( "D:/malajava" );
System.out.println( fod.toString() );
System.out.println( fod.getPath() );

1.1.4.20、比较File实例

尽管 File 类重写了 equals 方法,但除非两个 File 实例对应的路径名完全相同,

比如:

File first = new File( "D:/malajava" );
File second = new File( "D:/malajava" );

System.out.println( first == second ) ; // false
System.out.println( first.equals( second ) ); // true

否则即使两个File实例所表示的路径名在磁盘上是同一个目录或文件,通过equals方法比较后仍然返回false。

比如:

File first = new File( "D:/malajava" );
File second = new File( "D:\\malajava\\" );

System.out.println( first == second ) ; // false
System.out.println( first.equals( second ) ); // false

这里,不论 D:/malajava 还是 D:\malajava\都表示D盘根目录下的 malajava 目录,它们所表示的是磁盘上的同一个目录,但是这里通过 first.equals( second ) 比较后仍然返回 false

File类的实例本身仅仅是文件或目录的路径名的抽象表示形式,并不代表文件或目录本身。

因此 File 类重写了 equals 方法仅能比较两个File实例所表示的路径是否相等,并不能比较它们所表示的是否是同一个目录或文件。

1.1.4.21、转换为URI实例

URI 即 Universal Resource Identifier ,中文译作 统一资源标识符 ,是用于标识某一互联网资源的字符串。

File类中提供了将 File 实例转换为 URI 类型实例的方法:

public URI toURI()

举例:

File fod = new File( "D:/malajava/阿凡达.mp4" );
System.out.println( fod ) ;

URI uri = fod.toURI() ;
System.out.println( uri ) ;

1.1.4.22、转换为Path实例

从 Java 7 开始,Java语言中提供了 java.nio.file.Path 接口来表示磁盘上的文件或目录的路径,它是 File类的最佳替代者,因此从 Java 7 开始,File类提供了将 File 实例转换为 Path 实例的方法:

public Path toPath()

对于 toPath 返回的 Path 实例,这里仅作了解,后续章节( New Java IO ) 中会详细介绍它的用法。

举例:

File fod = new File( "D:/malajava/阿凡达.mp4" );
System.out.println( fod ) ;

Path path = fod.toPath();
System.out.println( path ) ;

虽然 FilePath都是文件或目录的路径名的抽象表示形式,但 Path要更合适些,同时 Path 接口中提供了大量的方法用来访问 文件或目录 ,因此将来建议使用 Path来替代与File有关的操作。

java.nio.file.Path 将在 New Java IO 一节中会详细讲解,此处暂不研究。

1.1.5、类方法

1.1.5.1、列出所有根路径

File类提供了获取当前文件系统的所有跟路径的方法:

public static File[]  listRoots()

该方法返回一个由所有的根路径名组成的File数组。

举例:

File[] roots = File.listRoots();
System.out.println( Arrays.toString( roots ) );

在 Windows 系统下,假设为硬盘分了三个分区: C盘、D盘、E盘,则以上程序运行后的输出内容为:

[C:\, D:\, E:\]

如果在此之前在电脑上插入了U盘,则U盘的根目录也会出现在数组中。

而在 Unix 、Linux 、macOS 等系统中,以上程序运行后的数据结果为:

[/]

这是因为在 Unix 、Linux 、macOS 等系统中仅有一个根路径。

1.1.5.2、创建临时文件

File类提供了用于创建临时文件的类方法:

  • 在默认临时文件目录中创建一个空文件,并使用给定前缀和后缀生成其名
public static File createTempFile( String prefix, String suffix )

其中:

  1. 参数prefix 表示临时文件名称的前缀,它必须是3个以上的字符组成
  2. 参数 suffix则表示临时文件名称的后缀,如果该参数为 null ,则默认的文件名后缀为 .tmp

临时文件名称的前缀和后缀之间的内容,由Java虚拟机确定,我们不必关注。

对于操作系统默认的临时目录,在不同操作系统中是不相同的,获取方法也不同。

Windows 系统中可以通过以下方式来获取默认的临时目录:

String temp = System.getenv( "TEMP" ); // TEMP 是环境变量中的 变量名称 ,请注意区分大小写

而在 macOS 系统中则可以通过以下方式来获取:

String temp = System.getenv( "TMPDIR" ); // TEPDIR 是环境变量中的 变量名称 ,请注意区分大小写

因为没有 Unix 、Linux 测试环境,这里不列出 Unix / Linux 系统中获取临时目录的方法。

举例:

public class CreateTempFileTest1 {

    public static void main(String[] args) {

        String temp = System.getenv( "TEMP" );
        System.out.println( "默认临时目录: " + temp );

        try {
            File f = File.createTempFile( "hello" , ".txt" );
            System.out.println( "临时文件路径: " + f ) ;
            System.out.println( "临时文件体积: " + f.length()  );

            /* 临时文件创建后,即可向临时文件中写入数据 或 从 临时文件中读取数据,此处暂不做研究 */

            // 临时文件只在程序运行期间存在,当程序退出时需要删除该文件
            f.deleteOnExit(); // 当 Java 虚拟机终止时,删除临时文件

        } catch ( IOException cause ) {
            throw new RuntimeException( "临时文件创建失败" , cause );
        }

    }

}

向临时文件中写入数据或者从临时文件中读取数据,需要使用文件输出流和文件输入流,这部分将在下一节讲解。

  • 在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称
public static File createTempFile( String prefix, String suffix, File directory )

其中:

  1. 参数prefix 表示临时文件名称的前缀,它必须是3个以上的字符组成
  2. 参数 suffix则表示临时文件名称的后缀,如果该参数为 null ,则默认的文件名后缀为 .tmp
  3. 参数 directory 表示临时文件所在的目录,如果该参数为 null ,则表示使用默认的临时目录

如果此方法成功返回,则可以保证:

  1. 由返回的抽象路径名表示的文件在此方法被调用之前不存在。
  2. 此方法及其所有变体都不会在虚拟机的当前调用中再次返回相同的抽象路径名。

此方法只提供了临时文件的创建功能,如果需要实现自动删除此方法创建的文件,可使用deleteOnExit()方法。

举例:

public class CreateTempFileTest2 {

    public static void main(String[] args) {

        try {
            // 创建一个File实例,它表示被创建的临时文件所在的目录
            File dir = new File( "D:/malajava" );

            // 在指定目录中创建临时文件,并使用给定的前缀和后缀确定其名称
            File f = File.createTempFile( "hello" , ".txt" , dir );
            System.out.println( "临时文件路径: " + f ) ;
            System.out.println( "临时文件体积: " + f.length()  );

            // 临时文件创建后,即可向临时文件中写入数据 或 从 临时文件中读取数据 ,此处暂不做研究 

            Thread.sleep( 15000 ); // 阻塞main线程15秒 (在线程睡眠期间可以在磁盘上查看创建的文件)

            f.deleteOnExit(); // 当 Java 虚拟机终止时,删除临时文件

        } catch ( IOException cause ) {
            throw new RuntimeException( "临时文件创建失败" , cause );
        } catch ( InterruptedException e ) {
            e.printStackTrace();
        }

    }

}

为了能够看到由程序所创建的临时文件,我们通过 Thread.sleep( 15000 ) 让main线程睡眠了15秒,在线程睡眠期间,可以进入到 D:/malajava 目录中,查看生成的临时文件。等到线程继续执行,Java虚拟机终止后,可以看到该文件又被删除了。( 在 CreateTempFileTest1 中也可以通过该方法进行测试 )

1.1.6、文件过滤

java.io 包中提供了用于对文件或目录进行过滤的接口:

  • java.io.FilenameFilter

  • java.io.FileFilter

结合File类提供的方法可以实现对文件或目录的过滤:

public String[] list( FilenameFilter filter )
public File[] listFiles( FilenameFilter filter )
public File[] listFiles( FileFilter filter )

接下来,我们将结合File类中的方法讲解FilenameFilterFileFilter的用法。

1.1.6.1、FilenameFilter

通过FilenameFilter接口的实现类的实例可实现根据文件或目录名称对文件或目录进行过滤。

FilenameFilter接口中定义了一个accept方法用于实现对文件或目录的过滤:

boolean accept( File dir, String name )

accept方法的参数中:

  • 第一个File类型参数类型的参数表示被筛选的文件或目录所在的目录
  • 第二个String类型的参数表示被筛选的文件或目录的名称

仅当accept方法返回 true 时,被筛选的文件会被保留在筛选后的文件列表中。

举例:

FilenameFilter filenameFilter = new FilenameFilter() {
    @Override
    public boolean accept ( File dir, String name ) {
        if ( name.endsWith( ".java" ) ) { // 如果 文件或目录的名称 是以 .java 为结尾
            return true; // 当返回true时当前文件或目录【会】保留在筛选后的列表中
        }
        return false; // 当返回false时当前文件或目录【不会】保留在筛选后的列表中
    }
};

File dir = new File( "D:/malajava/" );
// 通过 File 类提供的 listFiles 方法来筛选 dir 所表示的目录内部的文件或目录
File[] fods = dir.listFiles( filenameFilter ); // 作为参数传递给 listFiles 方法
// 使用 for-each 循环遍历数组
for( File fd : fods ) {
  System.out.println( fd.getName() ); // 逐个输出文件或目录名称
}

这里需要注意,请保证 D:/malajava 目录中存在子目录文件

1.1.6.2、FileFilter

通过FileFilter接口的实现类的实例可实现对文件或目录的过滤,不仅可以通过文件名称或目录名称过滤,也可以通过文件长度(体积)、访问时间等属性来过滤。

FileFilter接口中定义了一个accept方法用于实现对文件或目录的过滤:

boolean accept( File fod )

其中:

  • File类型的参数表示被筛选的文件或目录
  • 仅当accept方法返回true时,被筛选的文件或目录会保留在筛选后的列表中

举例:

final Calendar c = Calendar.getInstance(); // 获得 Calendar 实例
c.clear(); // 清除所有日历字段的值
c.set( 2019, 8, 20, 0, 0, 0 ); // 设置时间为 2019年9月20日00:00:00

final long time = c.getTimeInMillis(); // 获取 2019年9月20日00:00:00 对应的毫秒值

FileFilter fileFilter = new FileFilter() {
    @Override
    public boolean accept( File fod ) {
        // 判断当前文件或目录的最后修改时间是否在 2019年9月20日00:00:00 之后
        if ( fod.lastModified() >= time ) {
            return true; // 如果是就返回 true 则该 File 对象将包含在被选择的列表中
        }
        return false;
    }
};

File dir = new File( "D:/malajava/" );
File[] fods = dir.listFiles( fileFilter ); // 作为参数传递给 listFiles 方法
// 使用 for-each 循环遍历数组
for( File fd : fods ) {
  System.out.println( fd.getName() );
}

这里需要注意,请保证 D:/malajava 目录中存在子目录文件

同时要保证存在最后依次访问时间是在 2019年9月20日00:00:00 之前的文件或目录。

你可能感兴趣的:(Java中的File类)