IO流操作中大部分都是对文件的操作,所以Java就提供了File类给我们来操作文件。File类以抽象的方式表示文件名和目录路径名。该类主要用于文件和目录的创建、文件的删除、属性、重命名和获取等功能。下面将针对这些功能一一演示。
这里大家必须明白一个概念,其实目录就是文件夹。
构造器:File类提供了4个构造方法给我们使用。
1、通过一个路径字符串创建File对象:File(String pathname)
2、根据一个目录和一个子文件/目录创建File对象:File(String parent, String child)
3、根据一个父File对象和一个子文件/目录创建File对象:File(File parent, String child)
4、通过将给定的 file: URI 转换成一个抽象路径名来创建File对象:File(URI uri)
package com.gk.file.demo;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
public class Constructor {
public static void main(String[] args){
/*
* 创建File对象的4种方式。
*/
// 1、通过一个路径字符串创建File对象
File file = new File("d:/java/javase/file.java");
// 2、根据一个目录和一个子文件(文件夹)创建File对象
File file2 = new File("d:/java/javase/","file.java");
// 3、根据一个父File对象和一个子文件(文件夹)创建File对象
File file3 = new File(new File("d:/java/javase/"), "file.java");
// 4、通过将给定的 file: URI 转换成一个抽象路径名来创建File对象
try {
File file4 = new File(new URI("file:/d:/java/javase/file.java"));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
上述4种方法创建File对象之后并不代表在d盘上就存在java/javase/file.java文件了,仅仅只是以抽象表示形式指向了d:/java/javase/file.java。如果该文件(或文件夹)不存在,还需要我们创建它。所以,接下来,我们就来学习File类的创建功能。
创建文件
File类提供了5个创建文件(文件夹)的方法:
1、public boolean createNewFile()
2、public static File createTempFile(String prefix,String suffix)
3、public static File createTempFile(String prefix,String suffix, File directory)
4、public boolean mkdir()
5、public boolean mkdirs()
package com.gk.file.demo;
import java.io.File;
import java.io.IOException;
public class Create {
public static void main(String[] args) throws IOException{
// 为了操作方便,直接把异常抛出了,实际开发不建议这样做
fun(); // 返回值为boolean类型
fun2(); // 返回值为File类型
}
public static void fun() throws IOException{
File file = new File("d:/java");
File file2 = new File("d:/java/javase");
File file3 = new File("d:/java/javase/file.java");
/*
* public boolean mkdir()
* 创建文件夹,如果存在则不创建,但是要求父文件夹必须存在
*/
boolean flag = file.mkdir();
System.out.println(flag);
/*
* public boolean mkdirs()
* 创建文件夹,如果存在则不创建,如果父文件夹不存在也会创建父文件夹
*/
boolean flag2 = file2.mkdirs();
System.out.println(flag2);
/*
* public boolean createNewFile()
* 创建文件,如果存在则不创建,但是要求父文件夹必须存在,如果不存在则抛出IOException
*/
boolean flag3 = file3.createNewFile();
System.out.println(flag3);
}
public static void fun2() throws IOException{
/*
* public static File createTempFile(String prefix,String suffix)
* 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称
* prefix至少要3个字符,不然会抛出IllegalArgumentException
* suffix为null时,默认是".tmp"
*
* 所生成的文件会在prefix后面加上一串随机数
*/
File file = File.createTempFile("tempFile", ".java");
System.out.println(file.getAbsolutePath()); // 输出文件的绝对路径
/*
* public static File createTempFile(String prefix, String suffix, File directory)
* 与上一个方法类似,所不同是可以指定文件夹
*/
new File("d:/temp").mkdirs(); // 在d盘下生成一个temp文件夹
File file2 = File.createTempFile("tempFile", ".java", new File("d:/temp"));
System.out.println(file2.getAbsolutePath());
}
}
注意,如果创建的文件没有写路径的话,则默认在当前项目路径下。
删除文件
File类提供了2个删除文件(文件夹)的方法
1、public boolean delete()
2、public void deleteOnExit()
package com.gk.file.demo;
import java.io.File;
import java.io.IOException;
public class Delete {
public static void main(String[] args) throws IOException {
// 为了方便测试,直接在d盘上创建file.java
//System.out.println(new File("d:/file.java").createNewFile());
/*
* 值得注意的是,删除之后将不在回收站中
*/
fun();
fun2();
}
public static void fun() {
File file = new File("d:/file.java");
File file2 = new File("d:/tempFile");
boolean flag = file.delete(); // 删除文件
boolean flag2 = file2.delete(); // 删除文件夹,要求被删除的文件夹为空,不然将导致删除失败
System.out.println(flag);
System.out.println(flag2);
for (long x=1; x<=1000000L; x++){
System.out.println(x);
}
}
public static void fun2() {
File file = new File("d:/file.java");
file.deleteOnExit(); // 只有在虚拟机终止时,才会尝试执行删除操作
for (long x=1; x<=1000000L; x++){
System.out.println(x);
}
}
}
delete与deleteOnExit的区别:delete方法一经调用马上执行,调用deleteOnExit方法时并不会马上删除,只有在虚拟机终止时才会删除。读者可以边运行上面程序边观察d盘上file.java文件的消失时机。当运行fun时,即使for循环还没结束,但是只要delete方法运行结束了,d盘上的file.java文件就会消失;当运行fun2时,只有for循环结束且正常退出了JVM,d盘上的file.java文件才会消失。
其实createTempFile和deleteOnExit是对应的,使用场景是这样的:假设程序有个需求需要创建临时文件,这个临时文件可能作为存储使用,但是程序运行结束后,这个文件应该就被删除了。在哪里做删除操作呢,需要监控程序关闭吗,如果有很多地方可以中止程序,这个删除操作需要都放置一份吗?其实只要这么写,程序结束后文件就会被自动删除了。
File file = File.createTempFile("tmp",null);
// 这里对文件进行操作
file.deleteOnExit();
文件的属性
可以查看文件的属性,包括是否可读、可写、隐藏以及文件的大小等。
1、public boolean canRead()
2、public boolean canWrite()
3、boolean isHidden()
4、public long length()
5、public long lastModified()
package com.gk.file.demo;
import java.io.File;
import java.sql.Date;
import java.text.SimpleDateFormat;
public class Attribute {
public static void main(String[] args) {
fun();
}
public static void fun() {
File file = new File("d:/file.java");
/*
* public boolean canRead()
* 文件是否可读
*/
System.out.println("canRead : " + file.canRead());
/*
* public boolean canWrite()
* 文件是否可写
*/
System.out.println("canWrite : " + file.canWrite());
/*
* boolean isHidden()
* 文件是否隐藏
*/
System.out.println("isHidden : " + file.isHidden());
/*
* public long length()
* 文件的长度,以字节为单位
*/
System.out.println("length : " + file.length());
/*
* public long lastModified()
* 文件最后一次修改时间
*/
long time = file.lastModified();
Date date = new Date(time);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(dateFormat.format(date));
}
}
文件的判断
对于一个指定的File,判断其是文件还是文件夹,还可以判断存不存在。
1、public boolean isFile()
2、public boolean isDirectory()
3、public boolean exists()
package com.gk.file.demo;
import java.io.File;
public class Judge {
public static void main(String[] args) {
fun();
}
public static void fun() {
File file = new File("d:/file.java");
/*
* public boolean isFile()
* 指定的File是否是文件
*/
System.out.println("isFile : " + file.isFile());
/*
* public boolean isDirectory()
* 指定的File是否是文件夹
*/
System.out.println("isDirectory : " + file.isDirectory());
/*
* public boolean exists()
* 指定的File是否存在
*/
System.out.println("exists : " + file.exists());
}
}
文件重命名
对于指定的File,可以重命名。
public boolean renameTo(File dest)
package com.gk.file.demo;
import java.io.File;
public class Rename {
public static void main(String[] args) {
fun();
fun2();
}
public static void fun() {
File file = new File("d:/file.java");
/*
* public boolean renameTo(File dest)
* 对指定的File重命名
*/
System.out.println("renameTo : " + file.renameTo(new File("d:/rename.java")));
}
public static void fun2() {
File file = new File("d:/file.java");
/*
* public boolean renameTo(File dest)
* 对指定的File剪切并重命名
*/
System.out.println("renameTo : " + file.renameTo(new File("d:/java/rename.java")));
}
}
renameTo(File dest)方法有两个作用:1、如果改名前后路径相同就是单纯的重命名;2,如果改名前后路径不同就是重命名并剪切。
文件的获取
除了上诉功能外,File类还提提供了获取指定文件路径、文件名等一系列方法,还能获取指定盘符或文件夹下的所有文件。由于方法过多,一一列举即费时间又是完全没必要,所以依然建议多看官方文档。这里只列举几个常见的方法。
1、public String getAbsolutePath()
2、public String getPath()
3、public String getName()
4、public String[] list()
5、public File[] listFiles()
6、public String[] list(FilenameFilter filter)
7、public File[] listFiles(FilenameFilter filter)
package com.gk.file.demo;
import java.io.File;
import java.io.FilenameFilter;
public class Get {
public static void main(String[] args) {
fun();
fun2();
fun3();
}
public static void fun() {
File file = new File("file.java"); // 没写路径,说明此文件在当前项目下
/*
* public String getAbsolutePath()
* 获取文件的绝对路径
*/
System.out.println("getAbsolutePath : " + file.getAbsolutePath());
/*
* public String getPath()
* 获取文件的相对路径
*/
System.out.println("getPath : " + file.getPath());
/*
* public String getName()
* 获取文件的名称
*/
System.out.println("getName : " + file.getName());
}
public static void fun2() {
File file = new File("d:/");
/*
* public String[] list()
* 获取指定目录下的所有文件(文件夹)的名称数组
*/
String[] fileName = file.list();
for(String str : fileName){
System.out.println(str);
}
/*
* public File[] listFiles()
* 获取指定目录下的所有文件(文件夹)的File数组
*/
File[] files = file.listFiles();
for(File f : files){
System.out.println(f.isFile());
}
}
public static void fun3() {
File file = new File("d:/");
/*
* public String[] list(FilenameFilter filter)
* 与public String[] list()的区别是,这个方法具有过滤的功能
*/
String[] fileName = file.list(new FilenameFilter() { // 匿名内部类
@Override
public boolean accept(File dir, String name) {
// 只有是文件才返回,即过滤掉了文件夹,所以得到的fileName是文件名数组(不包含文件夹名)
File file = new File(dir, name);
boolean flag = file.isFile();
return flag;
}
});
for(String str : fileName){
System.out.println(str);
}
/*
* public File[] listFiles(FilenameFilter filter)
* 同样,这个方法也具有过滤的功能
*/
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
File file = new File(dir, name);
boolean flag = file.isFile();
return flag;
}
});
for(File f : files){
System.out.println(f.getAbsolutePath());
}
}
}
这里解释一下FilenameFilter(文件名称过滤器):FilenameFilter是一个接口,实现此接口的类实例可用于过滤器文件名,此接口只有public boolean accept(File dir, String name)这一个方法,此方法用于测试指定文件是否应该包含在某一文件列表中,返回true表示应该包含,返回false表示不包含。参数dir表示被找到的文件所在的目录;name表示文件的名称。
其实这里使用了策略模式,在list()方法中按照FilenameFilter的形式提供了这个策略,以完善list()在提供服务时所需的算法。提供了代码行为的灵活性。