1.File类简介
File类位于java.io包中。它面向文件层次级别操作、查看文件,而字节流、字符流操作数据时显然比之更底层。
学习File类包括以下几个重点:文件路径、文件分隔符、创建文件(目录)、删除文件(目录)、查看文件内容(输出目录内文件)、判断文件(是文件/目录?存在否?可读写执行?)、获取文件信息(文件名、路径名、大小等),最后还有如何筛选所需文件。
2.创建、删除文件/目录
File类有四个构造方法:File(String pathname)、File(String parent,String child)、File(File parent,String child)、File(URI uri),暂不考虑最后一个。
File file1 = new File("D:\myjava\a.txt"); //File(String pathname)
File file2 = new File("D:\myjava","a\b.txt"); //File(String parent,String child)
File file3 = new File(file2,"abc"); //File(File parent,String child)
new一个File对象后,表示创建了一个File实例,不代表在文件系统中创建了实际的文件。要创建实际的文件、目录,应该使用File类中提供的方法:
boolean createNewFile() throws IOException
:创建一个新的空文件,仅当文件不存在时才创建并返回true。static createTempFile()
:创建临时文件。boolean mkdir()
:创建空目录,仅当父路径存在且待创建目录不存在时才创建并返回true。注:不会递归创建父目录。boolean mkdirs()
:和mkdir()不同的是,mkdirs()会递归创建所有所需要的父路径。
例如,在d:myjava(已存在)中创建d:myjavaa.txt,d:myjavaaabcc.txt,以下提供了一种方法。
File file0 = new File("xyz.txt"); //相对路径,相对于system属性中的user.dir路径
File file1 = new File("D:\myjava\a.txt");
File file2 = new File("D:\myjava","a\abc");
File file3 = new File(file2,"c.txt");
try {
System.out.println(file1.createNewFile()); //try ... catch createNewFile()
System.out.println(file2.mkdirs());
System.out.println(file3.createNewFile());
} catch (IOException e) {
e.printStackTrace();
}
注意上面的双反斜线\
,因为Windows系统的文件分隔符为,而这是转义符号,因此需要对
自身进行转义。Unix操作系统中的文件分隔符号为
/
,但Windows也同样能够正确使用/
作为分隔符。
执行代码,由于第一次创建文件,所以都返回true,但第二次执行都将返回false,因为待创建文件都已存在。如下:
λ java TestCreate
true
true
true
λ java TestCreate
false
false
false
File类只提供了一个delete()方法用来删除文件和目录,且删除目录时只能删除空目录。注:此为永久删除,不进入回收站。
System.out.println(file1.delete()); //true
System.out.println(file2.delete()); //false
File file4 = new File("d:/myjava/a/abc/c.txt");
System.out.println(file4.delete()); //true
文件名和路径相关问题
每一个File对象都有父路径、文件名,两者结合就是文件的绝对路径。此外,路径还分为相对路径(抽象路径)、绝对路径。
以unix的路径命名方式为例,绝对路径/etc/ssh/ssh_config中/etc/ssh为dirname,即父路径,ssh_config为basename。Windows中也差不多,如绝对路径c:windowssystem32driversetchosts中的dirname为c:windowssystem32driversetc,basename部分为hosts。
以下是File类提供的与文件名、父路径、路径相关的方法。
getName()
:获取文件名。获取的内容是file对象中给定的抽象路径名,即路径的basename部分。getAbsoultePath()
:获取绝对路径名,即dirname/basename。getParent()
:获取父路径,即dirname。getPath()
:获取文件路径的字符串,其实调用的是toString()。可能返回相对路径、也可能绝对路径。见下文解释。File getAbsoulteFile()
:获取绝对路径的文件对象,注意返回File。File getParentFile()
:获取父路径的文件对象,注意返回File。
在new File时,可以给定相对路径(相对于user.dir),也可以给定绝对路径。例如,下面4个new File中,除了第一个是相对路径,其余三个都是绝对路径。
File file0 = new File("xyz.txt"); //相对路径,相对于system属性中的user.dir路径
File file1 = new File("D:\myjava\a.txt");
File file2 = new File("D:\myjava","a\abc");
File file3 = new File(file2,"c.txt");
当给定是相对路径时,则getParent()和getParentFile()无法正确获取到父路径,返回NULL,且getPath()返回的将是相对路径的文件名,即new File(PATH)给定什么PATH,就返回什么PATH。但无论如何,getAbsoultePath()总是能获取到绝对路径。
File file0 = new File("1.txt");
File file1 = new File("D:/myjava/a.txt");
File file2 = new File("D:/myjava","a/abc");
File file3 = new File(file2,"c.txt");
System.out.println("----------file0-----------------");
System.out.println(file0.getAbsoluteFile()); //D:myjavaio1.txt
System.out.println(file0.getAbsolutePath()); //D:myjavaio1.txt
System.out.println(file0.getName()); //1.txt
System.out.println(file0.getParent()); //null
System.out.println(file0.getParentFile()); //null
System.out.println(file0.getPath()); //1.txt
System.out.println("----------file1-----------------");
System.out.println(file1.getAbsoluteFile()); //D:myjavaa.txt
System.out.println(file1.getAbsolutePath()); //D:myjavaa.txt
System.out.println(file1.getName()); //a.txt
System.out.println(file1.getParent()); //D:myjava
System.out.println(file1.getParentFile()); //D:myjava
System.out.println(file1.getPath()); //D:myjavaa.txt
System.out.println("----------file2-----------------");
System.out.println(file2.getAbsoluteFile()); //D:myjavaaabc
System.out.println(file2.getAbsolutePath()); //D:myjavaaabc
System.out.println(file2.getName()); //abc
System.out.println(file2.getParent()); //D:myjavaa
System.out.println(file2.getParentFile()); //D:myjavaa
System.out.println(file2.getPath()); //D:myjavaaabc
System.out.println("----------file3-----------------");
System.out.println(file3.getAbsoluteFile()); //D:myjavaaabcc.txt
System.out.println(file3.getAbsolutePath()); //D:myjavaaabcc.txt
System.out.println(file3.getName()); //c.txt
System.out.println(file3.getParent()); //D:myjavaaabc
System.out.println(file3.getParentFile()); //D:myjavaaabc
System.out.println(file3.getPath()); //D:myjavaaabcc.txt
3. 文件判断和文件属性相关
new File对象时,无论这个对象是文件还是目录,new的方式是一样的,也就是说,从new File无法识别出这个对象是文件还是目录,也无法确认这个对象对应的文件是否存在。此外,这个文件是否可读、可写、可执行等也都可以进行判断。其实这些都算是文件的属性信息,除了这些信息外,文件名、文件大小、最近一次修改时间等也都是文件属性。
exists()
:File对象在文件系统中是否存在。isFile()
:File对象在文件系统中是否存在且是否为普通文件。isDirectory()
:File对象在文件系统中是否存在且是否为目录。canRead()
:File对象是否可读。canWrite()
:File对象是否可写。canExecute()
:File对象是否可执行。
还有两个获取常见属性的方法:
length()
:文件大小,单位字节。可用来判断是否为空文件、空目录。lastModified()
:最近一次修改时间,即mtime。
还可以设置读、写、执行、最近修改时间等属性。
setLastModified(long time)
:time用从1970-01-01开始的毫秒数表示。setExecutable(true/false)
:对所有用户是否可执行,参数为true或falsesetExecutable(true/false,true/false)
:第二个参数表示owneronly,为true时表示只有所有者可执行,否则表示所有用户可执行。setWritable(true/false)
:和setExecute()一样,也支持owneronly参数。setReadable(true/false)
:和setExecute()一样,也支持owneronly参数。setReadOnly()
:设置只读,设置成功返回true。
4. 列出目录内文件
File类中没有提供查看文件内容的方法,仅只提供了查看目录内容的方法,也就是列出目录内的文件列表。这些方法都只能列出当前目录内容,不会递归到子目录中去遍历。
String[] list()
:返回一个字符串数组,元素为此目录中文件的basename。String[] list(FilenameFilter filter)
:返回一个字符串数组,元素为满足过滤条件的basename。File[] listFiles()
:返回一个抽象路径名数组,元素为此目录中文件的basename。File[] listFiles(FileFilter filter)
:返回抽象路径名数组,元素为满足过滤条件的basename。File[] listFiles(FilenameFilter filter)
:返回抽象路径名数组,元素为满足过滤条件的baesname。
因为文件列表返回的是多个值,甚至是多个File对象,因此这些方法返回值都是数组形式。之所以是数组而不是集合,是因为数组中的元素数量是不可更改的,而列出目录中文件列表本就是列出当前时刻目录内文件的动作,如果有增、删元素的操作,岂非列出前是一个列表,实际列出的又是另一个列表?
首先看不带过滤器的list()和listFiles(),关于文件筛选的方法见后文。假设D:a目录内的结构如下:
d:a
|--a.sql
|--back.log
|--b
| |--e
| | |--1.txt
| | |--2.txt
| | `--3.txt
| `--f
| |--4.txt
| |--5.txt
| `--6.txt
|--c
| |--e
| | |--ace1.txt
| | |--ace2.txt
| | `--ace3.txt
| `--f
| |--4.txt
| |--5.txt
| `--6.txt
`--d
|--a.java
|--abc (1).txt
|--abc (2).txt
|--abc (3).txt
|--b.java
`--c.java
列出D:a内的文件列表。
File file1 = new File("d:/a");
String[] list = file1.list();
for (String f : list) {
System.out.println(f);
}
得到的结果为
a.sql
b
back.log
c
d
实际的过程是将目录内的文件名存放到了字符串数组中,再遍历数组。而且,得到的结果仅仅只是basename部分的文件名,不是绝对路径。实际上,因为存储在String[]中,完全没办法得到其绝对路径。因此,更好的方式是使用listFiles()方法,因为它返回的是File数组,其内每一个元素都是File对象,可以使用getAbsolutePath()来获取各元素的绝对路径。
File file1 = new File("d:/a");
File[] filelist = file1.listFiles();
for (File file : filelist) {
System.out.println(file.getAbsolutePath());
}
得到的结果为:
d:aa.sql
d:a
d:aack.log
d:ac
d:ad
关于列出目录,有如下几个示例,见:java显示目录文件列表和删除目录。
示例1:列出整个目录中的文件(递归)
示例2:列出整个目录中的文件(队列)
示例3:树形结构显示整个目录中的文件(递归)
示例4:删除整个目录
5.筛选文件
File类的listFiles()支持文件筛选功能。例如File[] listFiles(FileFilter filter)
,其中FileFilter为过滤器接口,需要实现该接口来筛选文件。
常用的筛选方法是根据文件名,其实也支持其他筛选条件,如是否可读、大小是否大于5M等。
import java.io.*;
public class Filter1 {
public static void main(String[] args) {
File dir = new File("d:/myjava");
getJavaFiles(dir);
}
public static void getJavaFiles(File dir) {
File[] files = dir.listFiles(new NameFilter());
for (File file:files) {
if(file.isDirectory()) {
getJavaFiles(file);
} else {
System.out.println(file.getAbsolutePath());
}
}
}
}
//实现FileFilter接口
class NameFilter implements FileFilter {
public boolean accept(File pathname) {
if(pathname.isDirectory()) { //为了支持递归筛选,判断目录
return true;
} else {
String name = pathname.getName();
return name.endsWith(".class")?true:false;
//return pathname.canRead()?true:false; //根据是否可读筛选
//return pathname.length()>5242880?true:false; //根据大小筛选great than 5MB?(5*1024*1024)
}
}
}
注:若您觉得这篇文章还不错请点击右下角推荐,您的支持能激发作者更大的写作热情,非常感谢!