本文简单介绍File类常用的方法和一些场景。两部分,第一部分作为介绍,第二部分给出代码例子。
(一)基础介绍
(1) 定义
File类可以表示“目录”或者“文件”。先来看一下File类的静态成员。
(2) 静态成员
public static final String pathSeparator // 路径分割符":"
public static final char pathSeparatorChar // 路径分割符':'
public static final String separator // 分隔符"/"
public static final char separatorChar // 分隔符'/'
这里给出了两种符号,每一个符号有两种类型,String和Char,通常我们都是用String。那么为什么要将" : "和" / "这样表示呢,这主要还是因为Linux和Windows系统的差异造成的,为了让程序能够跨平台使用,访问目录或者文件不出现"No such file or directory"错误,就有了这种分割符号的静态常量。打个比方,我们现在要在一个叫helloworld的目录下创建一个test.txt文件,那么在Linux和Windows下的写法分别是:
//Linux下写法
File file = new File("/helloworld/test.txt");
//Windows下写法
File file = new File("D:\\helloworld\\test.txt");
但是使用分隔符常量就可以合并唯一,不用再担心程序会运行在哪一种操作系统中:
File file = new File("D:" + File.separator + "tmp" + File.separator, "test.txt");
//或者
File file = new File("D:" + File.separator + "tmp" + File.separator + "test.txt");
不要怀疑哦,怎么又是两种写法,这两种写法结果都是一样,只不过是调用的不同的构造器而已,在(3)看一下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。
(3) 构造函数
File(File parent, String child) //创建一个新的 File实例从父母孩子抽象路径名和路径名字符串。
File(String pathname) //创建一个新的 File实例通过将给定路径名字符串转换为抽象路径名。
File(String parent, String child) //创建一个新的 File实例从一个父路径名字符串和一个孩子路径名字符串。
File(URI uri) //创建一个新的 File实例通过将给定 file: URI转换为一个抽象的路径名。
File提供了四种构造器,可以满足创建目录,子目录,多级目录,文件等等。
1、创建目录的方法
现在我需要在"E:/FileTest"下创建新目录helloworld:
方法1
File helloworld = new File("E:"+File.separator+"FileTest"+File.separator+"helloworld");
helloworld.mkdir();
方法2
URI uri = null;
try {
uri = new URI("file:/E:/FileTest/helloworld/");
} catch (URISyntaxException e) {
e.printStackTrace();
}
File helloworld = new File(uri);
helloworld.mkdir();
如果我只是需要在当前目录下创建目录helloworld(当前目录指的是java程序所在的工程目录),那么只要写个目录的名字就可以了,这就是相当于写了helloworld的相对路径了。
方法3
File helloworld = new File("helloworld");
helloworld.mkdir();
这个目录的完整路径是java工程所在目录,我的机器上是这样的:E:\CODE\Study\FileTest\helloworld。
2、创建子目录的方法
在工程目录的helloworld目录下创建子目录sub(x):
方法1:
File sub1 = new File("helloworld", "sub1");
sub1.mkdir();
方法2:
File sub2 = new File(helloworld, "sub2");
sub2.mkdir();
方法1和方法2的作用是,在当前目录下 "helloworlde/sub1"。它能正常运行的前提是“sub1/sub2”的父目录“helloworld”已经存在。
File sub3 = new File("helloworld/sub3");
sub3.mkdirs();
方法4:
File sub4 = new File("E:/CODE/Study/FileTest/helloworld/sub4");
sub4.mkdirs();
方法3和方法4不需要helloworld已经存在,也能正常运行;若“sub3/sub4”的父目路不存在,mkdirs()方法会自动创建父目录。
URI uri = new URI("file:/E:/CODE/Study/FileTest/helloworld/sub5");
File sub5 = new File(uri);
sub5.mkdirs();
3、新建文件的方法
在工程所在的当前的helloworld目录下创建文件"*.txt"
方法1
File helloworld = new File("helloworlde"); // 获取目录“helloworld”对应的File对象
File file1 = new File(helloworld, "1.txt");
try{
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
方法2
try {
File file2 = new File("helloworld", "2.txt");
file2.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
方法3
try {
File file3 = new File("E:/CODE/Study/FileTest/helloworld/3.txt");
file3.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
方法4
try {
URI uri = new URI("file:/E:/CODE/Study/FileTest/helloworld/4.txt");
File file4 = new File(uri);
file4.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
这四种方法都有一个共同的前提,那就是目录helloworld必须要存在,否则会出现
java.io.IOException: 系统找不到指定的路径异常。只不过方法1和方法2是通过相对目录完成创建文件的,而方法3是通过绝对路径,而方法4类似于3,只不过是将绝对路径对应的uri作为参数获得了helloworld的文件对象。
以上就是File构造函数的介绍以及用法。
(4) File API概览
boolean canExecute() //测试应用程序是否可以执行用此抽象路径名表示的文件。
boolean canRead() //测试应用程序是否可以读取文件用这种抽象的路径名。
boolean canWrite() //测试应用程序是否可以修改文件用这种抽象的路径名。
int compareTo(File pathname) //比较两个抽象的路径名字母顺序进行。
boolean createNewFile() //自动创建一个新的空文件被这个抽象路径名当且仅当一个文件,这个名字还不存在。
static File createTempFile(String prefix, String suffix) //在默认临时文件目录中创建一个空文件,使用给定的前缀和后缀来生成它的名字。
static File createTempFile(String prefix, String suffix, File directory) //创建一个新的空文件在指定的目录中,使用给定的前缀和后缀字符串生成它的名字。
boolean delete() //删除文件或目录用这种抽象的路径名。
void deleteOnExit() //请求的文件或目录用这个抽象路径名在虚拟机终止时被删除。
boolean equals(Object obj) //测试此抽象路径名的平等与给定的对象。
boolean exists() //检查文件或目录是否用这个抽象路径名的存在。
File getAbsoluteFile() //返回此抽象路径名的绝对形式。
String getAbsolutePath() //返回此抽象路径名的绝对路径名字符串。
File getCanonicalFile() //返回此抽象路径名的规范形式。
String getCanonicalPath() //返回此抽象路径名的规范路径名字符串。
long getFreeSpace() //返回的分区中未分配的字节数 named这个抽象的路径名。
String getName() //返回的文件或目录的名称用这种抽象的路径名。
String getParent() //返回此抽象路径名的路径名字符串的母公司或 null如果这个路径名不名一个父目录。
File getParentFile() //返回此抽象路径名的抽象路径名的母公司或 null如果路径名不名一个父目录。
String getPath() //将此抽象路径名转换为一个路径名字符串。
long getTotalSpace() //返回分区的大小 named这个抽象的路径名。
long getUsableSpace() //返回的字节数此虚拟机分区可用 named这个抽象的路径名。
int hashCode() //计算哈希代码抽象路径名。
boolean isAbsolute() //测试此抽象路径名是否绝对的。
boolean isDirectory() //测试文件是否用这个抽象路径名是一个目录。
boolean isFile() //测试文件是否用这个抽象路径名是一个正常的文件。
boolean isHidden() //测试文件是否被这个抽象路径名是一个隐藏文件。
long lastModified() //返回文件的时间用这个抽象路径名是最后修改。
long length() //返回文件的长度用这种抽象的路径名。
String[] list() //返回一个字符串数组命名目录中的文件和目录用这种抽象的路径名。
String[] list(FilenameFilter filter) //返回一个字符串数组的命名文件和目录用此抽象路径名表示的目录中满足指定过滤器。
File[] listFiles() //返回一个抽象路径名数组表示用此抽象路径名表示的目录中的文件。
File[] listFiles(FileFilter filter) //返回一个数组抽象路径名表示的目录中的文件和目录用这个抽象路径名满足指定过滤器。
File[] listFiles(FilenameFilter filter) //返回一个数组抽象路径名表示的目录中的文件和目录用这个抽象路径名满足指定过滤器。
static File[] listRoots() //列出可用的文件系统根。
boolean mkdir() //被这个抽象路径名创建目录。
boolean mkdirs() //由这个抽象路径名创建目录命名,包括任何必要的但不存在的父目录。
boolean renameTo(File dest) //重命名文件用这种抽象的路径名。
boolean setExecutable(boolean executable) //一个方便的方法来设置这个抽象路径名的所有者的执行权限。
boolean setExecutable(boolean executable, boolean ownerOnly) //集所有者或每个人都对这个抽象路径名的执行权限。
boolean setLastModified(long time) //设置文件或目录的最后修改时间被这抽象的路径名。
boolean setReadable(boolean readable) //一个方便的方法来设置这个抽象路径名的所有者的读权限。
boolean setReadable(boolean readable, boolean ownerOnly) //集所有者或每个人都对这个抽象路径名的读权限。
boolean setReadOnly() //标志着文件或目录被这个抽象路径名,只允许读取操作。
boolean setWritable(boolean writable) //一个方便的方法来设置这个抽象路径名的所有者的写权限。
boolean setWritable(boolean writable, boolean ownerOnly) //集所有者或每个人都对这个抽象路径名的写权限。
Path toPath() //返回一个 java.nio.file.Path对象由这个抽象路径。
String toString() //返回此抽象路径名的路径名字符串。
URI toURI() //构造一个 file: URI表示此抽象路径名。
URL toURL() 弃用。 这个方法不会自动转义字符在url是非法的。建议新代码抽象路径名转换为一个URL,首先将它转换成一个URI,通过toURI方法,然后通过URI.toURL URI转换成一个URL的方法。
下面的第二部分就展示一下常用的API。
(二)常用方法
写一些简单的代码,假设我在"E:FileTest"目录下进行操作,创建文件夹helloworld,创建文本文件若干,并在helloworld文件夹中创建新文件夹及文件。获取文件的名称,路径,修改时间等。除此之外还将说一下如何通过递归,获取目录下所有的文件路径信息,这对于文件列表的显示是非常好用的。
package IO;
import java.io.File;
import java.io.IOException;
/**
* Created by GFC on 2017/12/6.
*/
public class TextFile {
public static void main(String[] args) throws IOException {
File helloworld = new File("E:\\FileTest\\helloworld");
File file1 = new File("E:\\FileTest\\1.txt");
File file2 = new File("E:\\FileTest\\2.txt");
helloworld.mkdir();
file1.createNewFile();
file2.createNewFile();
System.out.println("helloworld的绝对路径: " + helloworld.getAbsolutePath());
//创建多级目录
//在helloworld下创建sub.txt文件
File helloworld2sub = new File("E:\\FileTest\\helloworlde2\\sub");
File helloworldsubtxt = new File("E:\\FileTest\\helloworld\\sub.txt");
helloworld2sub.mkdirs();
helloworldsubtxt.createNewFile();
//delete,exists,isDirectory测试,测试文件2.txt
File file = new File("E:" + File.separator + "FileTest" + File.separator + "2.txt");
if (file.exists()) {
file.delete();
}
System.out.println(file.isDirectory());
System.out.println(file.isFile());
file.createNewFile();
System.out.println("###########使用File类下的list方法进行遍历输出############");
//普通循环和递归循环输出FileTest下所有文件及文件夹
String type = null;
String folderName = "E:" + File.separator + "FileTest";
File folder = new File(folderName);
String[] fileList = folder.list();
for (String s : fileList)
System.out.println(s);
System.out.println("###########使用File类下的listFiles方法进行遍历输出############");
File[] fileList2 = folder.listFiles();
for (File f : fileList2) {
System.out.println(f.getName() + " " + (type = f.isDirectory() ? "Folder" : "File"));
//直接将File对象打印输出是完整路径
System.out.println(f);
}
System.out.println("###########使用递归方法进行遍历输出############");
print(folder);
}
public static void print(File file) {
if (file != null) {
if (file.isDirectory()) {
File[] fs = file.listFiles();
for (File f : fs) {
print(f);
System.out.println(file);
}
}
}
}
}
运行结果:
helloworld的绝对路径: E:\FileTest\helloworld
false
false
###########使用File类下的list方法进行遍历输出############
1.txt
2.txt
helloworld
helloworlde2
###########使用File类下的listFiles方法进行遍历输出############
1.txt File
E:\FileTest\1.txt
2.txt File
E:\FileTest\2.txt
helloworld Folder
E:\FileTest\helloworld
helloworlde2 Folder
E:\FileTest\helloworlde2
###########使用递归方法进行遍历输出############
E:\FileTest\1.txt
E:\FileTest\2.txt
E:\FileTest\helloworld\sub.txt
E:\FileTest\helloworld
E:\FileTest\helloworlde2\sub
E:\FileTest\helloworlde2
当我们想要遍历多级文件目录的时候,递归是一个很不错的选择,通过上述我们也能够看出来File对象打印出来的是该对象的绝对路径。这里只测试了部分常见功能,其它功能请查看第一部分的第四小节File类的API,每一个方法都标注了详细的说明。
参考内容:
https://www.imooc.com/video/3621
http://www.cnblogs.com/skywang12345/p/io_08.html