黑马程序员--IO流(File对象功能)

File是文件和目录路径名的抽象表示形式。
用户界面和操作系统使用与系统相关的路径名字符串 来命名文件和目录。此类呈现分层路径名的一个抽象的、与系统无关的视图。抽象路径名 有两个组件:
1.一个可选的与系统有关的前缀 字符串,比如盘符,”/” 表示 UNIX 中的根目录,”\\” 表示 Microsoft Windows UNC 路径名。
2.零个或更多字符串名称 的序列。
抽象路径名中的第一个名称是目录名,对于 Microsoft Windows UNC 路径名则是主机名。抽象路径名中第一个名称之后的每个名称表示一个目录;最后一个名称既可以表示目录,也可以表示文件。空 抽象路径名没有前缀和名称序列。
路径名字符串与抽象路径名之间的转换与系统有关。将抽象路径名转换为路径名字符串时,每个名称与下一个名称之间用一个默认分隔符 隔开。默认名称分隔符由系统属性 file.separator 定义,可通过此类的公共静态字段 separator 和 separatorChar 使其可用。将路径名字符串转换为抽象路径名时,可以使用默认名称分隔符或者底层系统支持的任何其他名称分隔符来分隔其中的名称。
无论是抽象路径名还是路径名字符串,都可以是绝对 路径名或相对 路径名。绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件。相反,相对路径名必须使用取自其他路径名的信息进行解释。默认情况下,java.io 包中的类总是根据当前用户目录来解析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。
调用此类的 getParent() 方法可以获取抽象路径名的父 路径名,它由路径名前缀以及路径名名称序列中的每个名称(最后一个除外)组成。对于任何具有绝对抽象路径名的 File 对象,如果其绝对抽象路径名以某个目录的绝对路径名开头,那么该目录的绝对路径名是该 File 对象的祖先。例如,抽象路径名 “/usr” 表示的目录是路径名 “/usr/local/bin” 所表示目录的一个祖先。
在处理 UNIX 平台的根目录,以及 Microsoft Windows 平台的盘符、根目录和 UNC 路径名时,将用到前缀这一概念。如下所示:
对于 UNIX 平台,绝对路径名的前缀始终是 “/”。相对路径名没有前缀。表示根目录的绝对路径名的前缀为 “/” 且名称序列为空。
对于 Microsoft Windows 平台,包含盘符的路径名前缀由驱动器号和一个 “:” 组成。如果路径名是绝对路径名,还可能后跟 “\”。UNC 路径名的前缀是 “\\”;主机名和共享名是名称序列中的前两个名称。没有指定驱动器的相对路径名没有前缀。
此类的实例可能表示(也可能不表示)实际文件系统对象,如文件或目录。如果它表示这种对象,那么该对象驻留在一个分区 中。分区是文件系统特定于操作系统的存储分区。一个存储设备(例如,物理磁盘驱动器、闪存、CD-ROM)可以包含多个分区。对象(如果有)将驻留在此路径名(绝对形式)某个祖先指定的分区上。
文件系统可以实现对实际文件系统对象上的某些操作(比如,读、写、执行)进行限制。这些限制统称为访问权限。文件系统可以对一个对象设置多个访问权限。例如,一个设置可能适用于对象的所有者,另一个设置则可能适用于所有其他用户。对象上的访问权限可能导致此类的某些方法执行失败。
File 类的实例是不可变的;也就是说,一旦创建,File 对象表示的抽象路径名将永不改变。
首先我们介绍list():返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。

package second;

import java.io.File;

/**
 * 我想打印C根目录下的所有文件或目录,包括隐藏目录
 */
public class FileDemo {
    public static void main(String []args){
        listDemo();
    }
    public static void listDemo(){
        String dir="C:\\"//当dir为文件时,file.list()会返回一个空,会导致报错,
        //所以有时为了严格要判断一下names
        //即调用list方法的file对象必须是封装的一个存在的目录
        File file=new File(dir);
        String []names=file.list();
        for(String name : names){
            System.out.println(name);
        }
    }
}

当然如果想打印所有磁盘跟目录下的文件或文件夹,则需要配合listRoots(),使用listRoots()会 列出可用的文件系统根。
下面我们做一个文件名过滤操作

package second;

import java.io.File;
import java.io.FilenameFilter;

/**
 * 我想打印E:\testdir目录下所有.java文件
 */
public class FileDemo {
    public static void main(String []args){
        File dir=new File("E:\\testdir");
        //这儿用到了文件名过滤器,用的是一个匿名内部类的形式
        String []arr=dir.list(new FilenameFilter(){
            @Override
            //当文件返回true时,则此name被记录到arr中
            public boolean accept(File dir, String name) {
                return name.endsWith(".java");//如果文件以.java结束则返回true
            }

        });
        for(String name :arr){
            System.out.println(name);
        }
    }
}

下面我们学习listFiles():返回一个抽象路径名数组,即File[],既然返回一个对象,那么久方便了我们的后续操作,像我们就可以得到这个file的name,length等等
下面我们做一个练习,列出指定目录下的文件或文件夹,包括子目录中的内容,也就是列出指定目录下的所有内容

package second;

import java.io.File;

/**
 * 我想打印指定目录下的文件或文件夹,包括子目录中的内容,也就是列出指定目录下的所有内容
 */
public class ListFilesDemo {
    public static void main(String []args){
        File dir=new File("E:\\testdir");
        showDir(dir);
    }
    public static void showDir(File dir){
        System.out.println(dir);//打印目录的
        File[] files=dir.listFiles();
        for(int i=0;i<files.length;i++){
            //判断一下当前是目录还是文件
            if(files[i].isDirectory())
                //如果是目录则递归调用,即自己调用自己
                showDir(files[i]);
            else
                //这个for循环只负责打印文件的
                System.out.println(files[i]);
        }
    }
}

注:递归一要注意结束条件,防止死递归
二要注意递归的层数,防止内存溢出
下面我们做一个删除带内容的目录

package second;

import java.io.File;

/**
 * 删除带内容的目录
 * 删除原理:
 * 在Windows中删除目录是从里往外删除的,这就需要用的递归
 */
public class DeletedirDemo {
    public static void main(String []args){
        File dir=new File("E:\\testdir");
        deleteDir(dir);
    }
    public static void deleteDir(File dir){
        File[] files=dir.listFiles();
        for(int i=0;i<files.length;i++){
            //判断一下当前是目录还是文件
            if(files[i].isDirectory())
                //如果是目录则递归调用,即自己调用自己
                deleteDir(files[i]);
            else
                //这个for循环只负责删除文件的
                System.out.println(files[i].toString()+":--file--:"+files[i].delete());
        }
        //删除目录
        System.out.println(dir.toString()+":--dir--:"+dir.delete());
    }
}

注:一、别删除系统目录,否则你懂得
二、delete方法会返回一个boolean类型的,可以根据这个返回值判断删除状态,
下面我们来做一个这样的操作,把指定目录下的同一类型的文件的绝对路径放在一个文本文件中,方便以后查找

package second;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 把指定目录下的同一类型的文件的绝对路径放在一个文本文件中,方便以后查找
 * 建立一个java文件列表文件
 * 思路:
 * 1.对指定文件进行递归
 * 2.过去递归过程中所有的java文件的路径
 * 将这些文件存储到一个集合中
 * 将集合中的数据写入到文件中
 */
public class DeletedirDemo {
    public static void main(String []args){
        File dir=new File("E:\\testdir");
        List<File>list=new ArrayList<File>();
        fileToList(dir,list);
        writeToFile(list,"E:\\testdir\\javaFileList.txt");
    }

    public static void fileToList(File dir,List<File>list){
        File[] files=dir.listFiles();
        for(File file:files){
            if(file.isDirectory())
                fileToList(file,list);
            else{
                if(file.getName().endsWith(".java")){
                    list.add(file);
                }
            }
        }
    }
    public static void writeToFile(List<File>list,String javaFileList){
        BufferedWriter bw=null;
        try {
            bw=new BufferedWriter(new FileWriter(javaFileList));
            for(File file:list){
                String path=file.getAbsolutePath();
                bw.write(path);
                bw.newLine();
                bw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(bw!=null)
                    bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这个练习相当于对以前的一个小小的复习了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值