Java笔记 - IO流 - File类

流只能操作数据,如果我们想对文件或文件夹操作,流就完成不了了,这时候就要用到java.io包中的另一个类:File类。
File类用来将文件或文件夹封装成对象,方便对文件或文件进行操作。File对象可以作为参数传递给流的构造函数,流的构造函数既可以接收String类型的文件名,也可以接收File类型的文件。

File类的常用方法

构造方法

File类的构造方法可以必须要有文件或文件夹的名称。
其中名称分隔符,在Windows系统下是’\ \’,在Unix系统下是’/’。
路径分隔符,在Windows系统下是分号,在Unix系统下是冒号。
为了使程序能在不同的系统下正常运行,可以使用System.getProperty(“file.separator”)来获取名称分割符,或者使用File类中提供的字段File.separator
File类指定的文件或文件夹可以是已存在的,也可以是不存在的。可以指定相对路径,也可以指定绝对路径。

File f1 = new File("a.txt");//相对路径
File f2 = new File("c:\\a.txt");//绝对路径
File f3 = new File("e:\\新建文件夹");
File f4 = new File("c:\\","a.txt");
File f = new File("c:\\");
File f5 = new File(f,"a.txt");
File f6 = new File("c:"+File.separator+"abc"+File.separator+"a.txt");

一般方法

获取

File file = new File("F:\\备份\\小说\\庆余年.txt");
String name = f1.getName();//获取文件或文件夹名称
String absPath = f1.getAbsolutePath();//获取绝对路径
String path = f1.getPath();//获取相对路径
long size = f1.length();//获取文件大小
long time = f1.lastModified();//获取修改时间,毫秒值
Date d = new Date(time);
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
String str_date = df.format(d);//获取修改时间的日期时间格式
//省略打印语句

输出结果:

name......庆余年.txt
absPath......F:\备份\小说\庆余年.txt
path......F:\备份\小说\庆余年.txt
size......7211449
time......1337259162000
str_date......2012517日 下午085242

创建和删除

创建和删除返回值类型的都是boolean型。
创建文件方法是createNewFile(),创建文件夹是mkdir(),创建多级文件夹目录是mkdirs()。在创建的时候如果目标已存在,则创建失败,不会覆盖。
删除文件或文件夹都是delete(),如果删除文件夹,文件夹中有内容,则删除失败。如果有多级目录,则只删除目录层次最深的那个文件夹,其他的只是父目录而已。
deleteOnExit():虚拟机终止,程序退出时删除文件或文件夹。防止IO流发生异常时,最后的delete语句有可能执行不到。

File file = new File("E:\\a.txt");
file.createNewFile();//创建文件

File dir = new File("E:\\新建文件夹");
dir.mkdir();//创建文件夹

File dirs = new File("E:\\a\\b\\c\\d");
dirs.mkdirs();//创建多级目录

dirs.delete();//只删除d文件夹

判断

exists():判断文件或文件夹是否存在
isDirectory():判断是否是文件夹
isFile():判断是否是文件

File f = new File("a.txt");
f.mkdir();
System.out.println(f.isDirectory());
System.out.println(f.isFile());

输出结果:

true
true
false

重命名

public boolean renameTo(File dest):重新命名此抽象路径名表示的文件。

File f1 = new File("c:\\0.mp3");
File f2 = new File("c:\\1.mp3");
File f3 = new File("d:\\2.mp3");
f1.renameTo(f2);//①
//f1.renameTo(f3);②

执行①发现c盘目录下的0.MP3文件重命名为1.MP3文件
执行②发现c盘目录下的0.MP3文件消失了,d盘目录下多了2.MP3文件,剪切了。

其他

public static File[] listRoots():列出可用的文件系统根。(就是列出系统盘符)
public long getFreeSpace():可用空间
public long getTotalSpace():总空间
public long getUsableSpace():可用空间,和Free一样。是给虚拟机用的。

File[] files = File.listRoots();
for (File file : files) {
    System.out.println(file);
}
File f = new File("F:\\我的壁纸很少\\a.jpg");
long l1 = f.getFreeSpace();
long l2 = f.getTotalSpace();
long l3 = f.getUsableSpace();
System.out.println(l1);
System.out.println(l2);
System.out.println(l3);

输出结果:

C:\
D:\
E:\
F:\
G:\
32449212416
88117391360
32449212416

遍历及过滤器

一般遍历

如果想遍历File指定目录下的所有文件和文件夹,就要用到一个方法
public String[] list():返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。

File f = new File("E:\\Test");
String[] names = f.list();
for(String name : names){
    System.out.println(name);
}

输出结果:

1.1
HelloWorld.class
HelloWorld.java
mypack
PackageDemo.java
ResourceTest.java

FilenameFilter

如果想要指定条件,就要加过滤器了,使用list方法的另一个重载形式:public String[] list(FilenameFilter filter)
实现了接口FilenameFilter的类就是过滤器,接口FilenameFilter只有一个方法
boolean accept(File dir, String name):测试指定文件是否应该包含在某一文件列表中。当且仅当在此抽象路径名及其表示的目录中的文件名或目录名上调用过滤器的 FilenameFilter.accept(java.io.File, java.lang.String) 方法返回 true 时,该名称才满足过滤器。

public class FilterByJava implements FilenameFilter {
    public boolean accept(File dir, String name) {  
        return name.endsWith(".java");
    }
}

public class FileListDemo {
    public static void main(String[] args) {
        File f = new File("E:\\Test");
        String[] names = f.list(new FilterByJava());
        for(String name : names){
            System.out.println(name);
        }
    }
}

输出结果:

HelloWorld.java
PackageDemo.java
ResourceTest.java

FileFilter

刚才我们过滤的内容是文件或文件夹的名字。如果我们只想看非隐藏的文件,不想看隐藏的文件,这时候就不能过滤名称了,要过滤文件或文件夹的属性,过滤器就不能实现FilenameFilter了,就要实现FileFilter接口。
FileFilter接口也只有一个方法:
boolean accept(File pathname):测试指定抽象路径名是否应该包含在某个路径名列表中。当且仅当在路径名上调用过滤器的 FileFilter.accept(java.io.File) 方法返回 true 时,该路径名才满足过滤器。

public class FilterByHidden implements FileFilter {
    public boolean accept(File pathname) {
        return !pathname.isHidden();
    }
}

public class FileListDemo{
    public static void main(String[] args) throws IOException{  
        File f = new File("E:\\Test");
        File[] files = f.listFiles(new FilterByHidden());
        for (File file : files) {
            System.out.println(file);
        }       
    }
}

输出结果:

E:\Test\1.1
E:\Test\HelloWorld.class
E:\Test\HelloWorld.java
E:\Test\mypack
E:\Test\PackageDemo.java

总结:list方法返回String类型的数组,它有一个重载可以接收FilenameFilter类型的过滤器用来过滤文件或文件夹名称。
listFiles方法返回File类型的数组,它有两个重载,一个可以接收FileFilter类型的过滤器用来过滤文件或文件夹属性,一个可以接收FilenameFilter类型的过滤器用来过滤文件或文件夹名称。

深度遍历

在之前的遍历过程中,我们只能遍历File对象指定的目录中的文件或文件夹。如果我们想对文件夹中的内容继续遍历,就要重新思考。

public static void main(String[] args) {
    File dir = new File("E:\\TEST\\");
    listAll(dir);
}

public static void listAll(File dir) {
    System.out.println("dir:"+dir.getAbsolutePath());
    File[] files = dir.listFiles();
    for (int i = 0; i < files.length; i++) {
        File file = files[i];
        if (file.isDirectory()) {
            listAll(files[i]);
        }else{
            System.out.println("flie:"+files[i].getAbsolutePath());
        }
    }
}

输出结果:

dir:E:\TEST
dir:E:\TEST\1.1
flie:E:\TEST\1.1\HelloWorld.class
flie:E:\TEST\1.1\HelloWorld.java
flie:E:\TEST\HelloWorld.class
flie:E:\TEST\HelloWorld.java
dir:E:\TEST\mypack
dir:E:\TEST\mypack\hah
dir:E:\TEST\mypack\hah\heh
dir:E:\TEST\mypack\hah\heh\xix
flie:E:\TEST\mypack\hah\heh\xix\PackageDemo.class
flie:E:\TEST\PackageDemo.java
flie:E:\TEST\ResourceTest.java

在这个例子中,程序调用自身的编程技巧称为递归。

如果我们想把Test这个文件夹整个删掉,就要从里往外删,只要文件夹中有内容,就删不掉的。也要用到递归的思想。

public static void main(String[] args) {
    File dir = new File("E:\\TEST - 副本");
    deleteAll(dir);
}

public static void deleteAll(File dir) {
    File[] files = dir.listFiles();
    for (int i = 0; i < files.length; i++) {
        if (files[i].isDirectory()) {
            deleteAll(files[i]);
        }else{
            System.out.println(files[i]+":"+files[i].delete());
        }
    }
    System.out.println(dir+":"+dir.delete());
}

输出结果:

E:\TEST - 副本\1.1\HelloWorld.class:true
E:\TEST - 副本\1.1\HelloWorld.java:true
E:\TEST - 副本\1.1:true
E:\TEST - 副本\HelloWorld.class:true
E:\TEST - 副本\HelloWorld.java:true
E:\TEST - 副本\mypack\hah\heh\xix\PackageDemo.class:true
E:\TEST - 副本\mypack\hah\heh\xix:true
E:\TEST - 副本\mypack\hah\heh:true
E:\TEST - 副本\mypack\hah:true
E:\TEST - 副本\mypack:true
E:\TEST - 副本\PackageDemo.java:true
E:\TEST - 副本\ResourceTest.java:true
E:\TEST - 副本:true

递归

递归就是程序调用自身的编程技巧。
不止是直接调用,如果间接调用也算是递归。

public static void show(){
    method();
}
public static void method(){
    show();
}

这个也是递归。但是这样反复调用,只进栈不出栈,栈内存就溢出了。
所以使用递归要注意两点:
1. 递归一定明确条件。否则容易栈溢出。
2. 注意一下递归的次数。 次数太多了容易栈溢出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值