Java IO: File

File类位于JDK的java.io这个包下。

一个File类既可以代表一个文件,也可以代表一个目录。

构造器

要使用File,首先需要通过构造器构造它的一个实例:

File file1 = new File("/a/b");
File file2 = new File("C:\a\b.dat");

构造File类需要给它指定一个路径,比如上面代码中的/a/b,C:\a\b.dat。路径可以代表一个文件,也可以代表一个目录。路径分隔符依据操作系统的不同而不同,在类Unix系统中,分隔符是/,而在windows操作系统中,分隔符是\,如果在代码中以硬编码的方式写死了路径分隔符,那么代码的可移植性就不高。可以通过File.separator或者是File.separatorChar来获取当前操作系统的路径分隔符。

File的构造器中的路径参数也支持绝对路径和相对路径,像上面的代码用的是绝对路径。那么相对路径相对的是哪个路径呢?Java会默认采用user.dir作为当前路径,可以通过System.getProperty("user.dir")来得到这个路径,这个路径也是JVM启动时所在的路径。

File也提供了另外一种构造器:

File(String parent, String child)
File(File parent, String child)

这两个构造器可以让你在构造文件或目录时指定它的父目录。

路径与名字

File类包含了诸多获取路径和路径名字的方法,这些方法看似差别不大却又别有洞天,可以通过下面几段代码来看看区别:

执行以下代码:

File file = new File(".");
System.out.println("Absolute path = " + file.getAbsolutePath());
System.out.println("Canonical path = " + file.getCanonicalPath());
System.out.println("Name = " + file.getName());
System.out.println("Parent = " + file.getParent());
System.out.println("Path = " + file.getPath());
System.out.println("Is absolute = " + file.isAbsolute());

得到的结果是:

Absolute path = C:prjooksioch02codePathInfo.
Canonical path = C:prjooksioch02codePathInfo
Name = .
Parent = null
Path = .
Is absolute = false

执行以下代码:

File file = new File("C:
eports2015..2014February");
System.out.println("Absolute path = " + file.getAbsolutePath());
System.out.println("Canonical path = " + file.getCanonicalPath());
System.out.println("Name = " + file.getName());
System.out.println("Parent = " + file.getParent());
System.out.println("Path = " + file.getPath());
System.out.println("Is absolute = " + file.isAbsolute());

得到的结果是:

Absolute path = C:
eports2015..2014February
Canonical path = C:
eports2014February
Name = February
Parent = C:
eports2015..2014
Path = C:
eports2015..2014February
Is absolute = true

执行以下代码:

File file = new File("");
System.out.println("Absolute path = " + file.getAbsolutePath());
System.out.println("Canonical path = " + file.getCanonicalPath());
System.out.println("Name = " + file.getName());
System.out.println("Parent = " + file.getParent());
System.out.println("Path = " + file.getPath());
System.out.println("Is absolute = " + file.isAbsolute());

得到的结果是:

Absolute path = C:prjooksioch02codePathInfo
Canonical path = C:prjooksioch02codePathInfo
Name =
Parent = null
Path =
Is absolute = false

从这里可以看出来,file.getAbsolutePath()会把相对路径的信息也打印出来,读起来并不是非常直观的,而file.getCanonicalPath()总是以对人类阅读友好的方式打印路径。如果File的入参是绝对路径,那么getName和getPath只打印入参,并且getParent为null。

得到文件/目录信息

前面说过,File可以是一个文件,也可以代表一个目录,如何知道File代表的是哪一个呢?通过以下两个方法就可以知道:

boolean isDirectory()
boolean isFile()

有时候我们想知道File代表的那个文件或目录是否在文件系统中存在,boolean exists()会告诉你。

在类Unix文件系统中,隐藏文件通常以.开头,比如用户的home目录下的.bash_profile,同样在windows中也会有隐藏文件,可通过isHidden()来判断一个文件是否是隐藏文件。

通过length()可以获得文件的大小。

通过lastModified()可以获得文件的最后修改时间,这个时间是距离(1970,1,1)的毫秒数。通常可以通过比较一个文件的最后修改时间来判断文件是否被修改过。

列举某个目录

可通过File[] listRoots()来列举当前文件系统的根目录。

在windows下,就是列出所有的盘符:

C:
D:
E:
F:

在Unix中,只有一个,那就是/。

如果要列出某个特定目录下的文件和目录呢,有以下方法:

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

以上方法中,返回String[]的,则是列举出所有文件或目录的名字。返回File[]的,则是所有文件或目录所代表的File对象。FileFilter和FilenameFilter是过滤器,能让你在列举目录时选择过滤掉哪些文件或目录。

获取磁盘空间信息

File提供了三个方法可以让你得知某个分区的磁盘空间的信息:

long getFreeSpace() //获取剩余空间
long getTotalSpace() //获取总空间大小
long getUsableSpace() //获取剩余可用空间

尽管getFreeSpace和getUsableSpace看起来差不多,但实际上是有差别的,getUsableSpace会进行更多细致的检查,比如当前JVM进程是否对该目录有写权限,以及另外一些操作系统的限制等,但getFreeSpace和getUsableSpace返回的值只能当做一个参考值,因为有可能有其他的进程正在读写这个磁盘空间。

下面是一个例子:

File[] roots = File.listRoots();
for (File root: roots) {
  System.out.println("Partition: " + root);
  System.out.println("Free space on this partition = " +
  root.getFreeSpace());
  System.out.println("Usable space on this partition = " +
  root.getUsableSpace());
  System.out.println("Total space on this partition = " +
  root.getTotalSpace());
  System.out.println("***");
}

输出结果为:

Partition: C:
Free space on this partition = 143271129088
Usable space on this partition = 143271129088
Total space on this partition = 499808989184
***
Partition: D:
Free space on this partition = 0
Usable space on this partition = 0
Total space on this partition = 0
***
Partition: E:
Free space on this partition = 733418569728
Usable space on this partition = 733418569728
Total space on this partition = 1000169533440
***
Partition: F:
Free space on this partition = 33728192512
Usable space on this partition = 33728192512
Total space on this partition = 64021835776
***

对文件或目录进行修改

如果想创建一个文件,使用boolean createNewFile()将会创建一个新的空文件,同样,创建一个目录可以用boolean mkdir() 或者boolean mkdirs() ,如果中间目录不存在,后者会创建好所有中间目录,而前者将会报错某个目录不存在。

有时候你希望创建一个临时文件,可以使用static File createTempFile(String prefix, String suffix),这个方法将会默认把临时文件放在用户的临时文件夹中,如果你想指定临时文件存放的地方,可以使用static File createTempFile(String prefix, String suffix, File directory)指定该目录。

文件权限

从Java 1.6开始,增加了对文件权限修改的接口。

boolean setExecutable(boolean executable)
boolean setExecutable(boolean executable, boolean ownerOnly)
boolean setReadable(boolean readable)
boolean setReadable(boolean readable, boolean ownerOnly)
boolean setWritable(boolean writable)
and boolean setWritable(boolean writable boolean ownerOnly)

同时提供以下接口获取文件权限信息:

boolean canRead()
boolean canWrite()
boolean canExecute()

File类中的字段信息

File 类中提供了四个类常量:

public static final char separatorChar:与系统有关的默认名称分隔符。此字段被初始化为包含系统属性 file.separator 值的第一个字符。在 UNIX 系统上,此字段的值为 '/';在 Microsoft Windows 系统上,它为 '\'public static final String separator:与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。此字符串只包含一个字符,即 separatorChar。
public static final char pathSeparatorChar:与系统有关的路径分隔符。此字段被初始为包含系统属性 path.separator 值的第一个字符。此字符用于分隔以路径列表 形式给定的文件序列中的文件名。在 UNIX 系统上,此字段为 ':';在 Microsoft Windows 系统上,它为 ';'public static final String pathSeparator:与系统有关的路径分隔符,为了方便,它被表示为一个字符串。此字符串只包含一个字符,即 pathSeparatorChar。

示例:

String pathSeparator = File.pathSeparator;
//System.out.println(pathSeparator);//路径分隔符 windows:分号;  linux:冒号:

String separator = File.separator;
//System.out.println(separator);// 文件名称分隔符 windows:反斜杠  linux:正斜杠/

System.out.println(File.separator);          //  
System.out.println(File.separatorChar);      //  
System.out.println(File.pathSeparator);      //  ;
System.out.println(File.pathSeparatorChar);  //  ;

常用方法

(1)获取文件或目录的详细信息

String getName():     返回由此抽象路径名表示的文件或目录的名称。
long length() :       返回由此抽象路径名表示的文件的长度。(只能返回文件大小,不能直接返回目录大小)
boolean exists() :    测试此抽象路径名表示的文件或目录是否存在。
boolean isHidden() :  测试此抽象路径名指定的文件是否是一个隐藏文件。
boolean canRead() :   测试应用程序是否可以读取此抽象路径名表示的文件。
boolean canWrite() :  测试应用程序是否可以修改此抽象路径名表示的文件  
long lastModified() : 返回此抽象路径名表示的文件最后一次被修改的时间。(毫秒值)
String toString() :   返回此抽象路径名的路径名字符串。boolean isAbsolute():  测试File对象对应的文件或目录是否是绝对路径。
String getParent() :  返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。(返回父目录名称) 
File getParentFile() :返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。(返回父目录的File对象)

注意:以上都是对应于 File 对象的属性信息,如果File对象是一个不存在的文件或目录,返回的都是对应属性的默认值,例:获取的length()为0,isFile()为False等, name,path这些都是有值的,因为这些属性是通过构造方法创建 File 时指定的,而其他的属性都是默认值。

(2)获取文件或目录的路径

String getPath() : 将此抽象路径名转换为一个路径名字符串。
File getAbsoluteFile() : 返回此抽象路径名的绝对路径名形式。
String getAbsolutePath():返回此抽象路径名的绝对路径名字符串。 返回绝对路径,从根目录开始导航
File getCanonicalFile(): 返回此抽象路径名的规范形式。
String getCanonicalPath() :返回此抽象路径名的规范路径名字符串。规范路径就是路径里没有./或../或/,会把这些自动解析

(3)操作文件或目录

boolean createNewFile():当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。(只创建文件)
boolean delete(): 删除此抽象路径名表示的文件或目录。(可以删除文件或删除空目录)删除成功,返回true,失败false。 
boolean equals(Object obj):测试此抽象路径名与给定对象是否相等。
boolean mkdir() : 创建此抽象路径名指定的目录。(只能创建一级目录)必须确保父目录存在,否则创建失败。
boolean mkdirs(): 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。 (可以创建多级目录)如果父目录不存在,会一同创建父目录
boolean renameTo(File dest) :重新命名此抽象路径名表示的文件。(可以给文件或目录重命名)

(4)判断是文件还是目录

boolean isFile() :测试此抽象路径名表示的文件是否是一个标准文件。
boolean isDirectory():测试此抽象路径名表示的文件是否是一个目录。

(5)获取目录的下一级

String[] list() :返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
File[] listFiles() :返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。(获取下一级的文件/目录的File对象)
static File[] listRoots():列出可用的文件系统根。

(6)获取功能的方法

获取绝对路径名

public String getAbsolutePath() :返回此File的绝对路径名字符串。

获取的是构造方法中传递的路径,无论路径是绝对的还是相对的,getAbsolutePath方法返回的都是绝对路径。

Demo:

File f1 = new File("E:\a.txt");
String absolutePath2 = f1.getAbsolutePath();
System.out.println(absolutePath);      // E:\a.txt

File f2 = new File("a.txt");
String absolutePath2 = f2.getAbsolutePath();
System.out.println(absolutePath);       // E:\a.txt

获取路径名

public String getPath() :将此File转换为路径名字符串。

获取的构造方法中传递的路径,File 类中的 toString方法调用的 getPath 方法。

Demo:

 File f1 = new File("E:\java\a.txt");
 File f2 = new File("a.txt");
 String path1 = f1.getPath();
 System.out.println(path1);  // E:javaa.txt
 String path2 = f2.getPath();
 System.out.println(path2);  //a.txt

获取文件或目录名称

public String getName() :返回由此File表示的文件或目录的名称。

获取的就是构造方法传递路径的结尾部分(文件/文件夹)。

Demo:

File f1 = new File("E:\java\a.txt");
String name1 = f1.getName();
System.out.println(name1);   //a.txt

File f2 = new File("E:\java");
String name2 = f2.getName();
System.out.println(name2);   // java

获取文件长度

public long length() :返回由此File表示的文件的长度。

获取的是构造方法指定的文件的大小,以字节为单位。注意:① 文件夹是没有大小概念的,不能获取文件夹的大小;② 如果构造方法中给出的路径不存在,那么length方法返回0。

Demo:

File f1 = new File("E:\java\a\1.jpg");   // 该文件存在
long l1 = f1.length();
System.out.println(l1);//78831字节

File f2 = new File("E:\java\a\2.jpg");   // 该文件不存在
System.out.println(f2.length());//0

File f3 = new File("E:\java\a");          // a 为一个文件夹
System.out.println(f3.length());//0 文件夹没有大小概念的

(7)判断功能的方法

判断文件或目录是否存在

public boolean exists() :此File表示的文件或目录是否实际存在。

用于判断构造方法中的路径是否存在,存在为 true;不存在为 false。

Demo:

 File f1 = new File("E:\java\aaa\bbb");
 System.out.println(f1.exists());//true

 File f2 = new File("E:\java\aaa\bb");   // 该路径不存在
 System.out.println(f2.exists());//false

 File f3 = new File("a.txt");              //相对路径 E:javaaa.txt
 System.out.println(f3.exists());//true

 File f4 = new File("a.txt");               // 该文件不存在
 System.out.println(f4.exists());//false

File 表示的是否为目录

public boolean isDirectory() :此File表示的是否为目录。

用于判断构造方法中给定的路径是否以文件夹结尾。 是:true; 否:false。注意:使用该方法前提,路径必须是存在的,否则都返回false,与下面方法互斥。

File 表示的是否为文件

public boolean isFile() :此File表示的是否为文件。

用于判断构造方法中给定的路径是否以文件结尾。是:true;否:false。注意:使用该方法前提,路径必须是存在的,否则都返回false,与上面方法互斥。

Demo:

File f1 = new File("E:\java\aaa\bbb");
//不存在,就没有必要获取
if(f1.exists()){
  System.out.println(f1.isDirectory());
  System.out.println(f1.isFile());
}

File f2 = new File("E:\java\aaa\bbb");
if(f2.exists()){
   System.out.println(f2.isDirectory());//true
   System.out.println(f2.isFile());//false
}

File f3 = new File("E:\java\aaa\bbb\a.txt");
if(f3.exists()){
    System.out.println(f3.isDirectory());//false
    System.out.println(f3.isFile());//true
}

(8)创建删除功能的方法

创建文件

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

创建文件的路径和名称在构造方法中给出(构造方法的参数)。返回值:布尔值;true:文件不存在,创建文件,返回 true;false:文件存在,不会创建,返回 false。注意:① 此方法只能创建文件,不能创建文件夹;② 创建文件的路径必须存在,否则会抛出异常。

Demo:

File f1 = new File("E:\java\aaa\bbb\a.txt");
 boolean b1 = f1.createNewFile();
 System.out.println("b1:"+b1);                // true 成功创建

 File f2 = new File("bbb\2.txt");
 System.out.println(f2.createNewFile());

 File f3 = new File("bbb\新建文件夹");
 System.out.println(f3.createNewFile());    //创建的是一个文件,不是文件夹,不要被名称迷糊,要看类型

 File f4 = new File("abc\3.txt");
 System.out.println(f4.createNewFile());     //路径不存在,抛出IOException

删除文件或者目录

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

创建文件夹的路径和名称在构造方法中给出(构造方法的参数)。返回值:true:文件夹不存在,创建文件夹;false:文件夹存在,不会创建,构造方法中给出的路径不存在也会返回 false。注意:此方法只能创建文件夹,不能创建文件。

创建单个目录

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

既可以创建单级文件夹,也可以创建多级文件夹。创建文件夹的路径和名称在构造方法中给出(构造方法的参数)。返回值:true:文件夹不存在,创建文件夹;false:文件夹存在,不会创建,构造方法中给出的路径不存在也会返回 false。

注意:此方法只能创建文件夹,不能创建文件。

Demo:

File f1 = new File("java\aaa\aa");
 boolean b1 = f1.mkdir();
 System.out.println("b1:"+b1);         // true

 File f2 = new File("java\111\222\333\444");
 boolean b2 = f2.mkdirs();
 System.out.println("b2:"+b2);         // true

 File f3 = new File("java\abc.txt");
 boolean b3 = f3.mkdirs();            //看类型,是一个文件
 System.out.println("b3:"+b3);

 File f4 = new File("jav\ccc");
 boolean b4 = f4.mkdirs();            //不会抛出异常,路径不存在,不会创建
 System.out.println("b4:"+b4);

创建文件或目录

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

该方法删除构造方法路径中给出的文件 / 文件夹。返回值:true:文件 / 文件夹删除成功,返回 true;false:文件夹中有内容,不会删除返回 false;构造方法中路径不存在false。

注意:① delete方法是直接在硬盘删除文件/文件夹,不走回收站,删除要谨慎;② delete方法,如果此File表示目录,则目录必须为空才能删除。

Demo:

File f1 = new File("java\新建文件夹");
boolean b1 = f1.delete();
System.out.println("b1:"+b1);

File f2 = new File("java\abc.txt");
System.out.println(f2.delete());

扩展:创建临时文件,通常结合 deleteOnExit() 使用

public static File createTempFile(String prefix,String suffix) throws IOException在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。调用此方法等同于调用 createTempFile(prefix, suffix, null)。
public static File createTempFile(String prefix,String suffix,File directory)throws IOException在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。

prefix:用于生成文件名的前缀字符串:必须至少三个字符。

suffix:用于生成文件名的后缀字符串:如果为 null,默认为 “.tmp”。

directory:将创建的文件所在的目录;如果使用默认临时文件目录,则该参数为 null。

public void deleteOnExit():当退出JVM时,删除文件,一般用于删除临时文件

Demo:

@Test
public void test() throws IOException{
    File tempFile = File.createTempFile("Hello", ".tmp");
    //....省略代码
    tempFile.deleteOnExit();
}

五、目录的遍历

File 类遍历(文件夹)目录功能

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

注意:

① list 方法和 listFiles 方法遍历的是构造方法中给出的目录。
② 如果构造方法中给出的目录的路径不存在,会抛出空指针异常。
③ 如果构造方法中给出的路径不是一个目录,也会抛出异常。
④ 调用listFiles方法的File对象,表示的必须是实际存在的目录,否则返回null,无法进行遍历。

Demo:

/*
public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
遍历构造方法中给出的目录,会获取目录中所有的文件/文件夹,把文件/文件夹封装为File对象,多个File对象存储到File数组中
*/
/*
public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
遍历构造方法中给出的目录,会获取目录中所有文件/文件夹的名称,把获取到的多个名称存储到一个String类型的数组中
*/
public void listSubFiles(File dir) {
    if (dir != null && dir.isDirectory()) {
        File[] listFiles = dir.listFiles();
        if (listFiles != null) {
            for (File sub : listFiles) {
                listSubFiles(sub);
            }
        }
    }
    System.out.println(dir);
}

原文地址:https://www.cnblogs.com/itfky/p/13728942.html