一、简介

File类是“文件”和“目录名”的抽象表示形式。因此在java语言中,File类既可以表示文件也可以表示目录。

尽管java.io定义的大多数类是实行流式操作的,而File类则不是,它没有指定信息怎样从文件读取或向文件存储。File描述了文件本身的属性,直接处理文件和文件系统,是唯一一个与文件本身有关的操作。

1.1 File的继承与实现接口

File 直接继承于Object,实现了Serializable接口和Comparable接口。

public class File implements Serializable, Comparable<File>
  • File类实现Serializable接口,意味着File对象支持序列化操作。
  • File类实现Comparable接口,意味着File对象之间可以比较大小,此外File能直接被存储在有序集合(如TreeSet、TreeMap中)。
结构图如下:

1.2 File使用注意事项

1、创建File类对象时要注意的地方

    首先我们要区分两个名词:“绝对路径”和“相对路径”。
    绝对路径:即完整的路径,比如:D:\MyCode\Java\FileDemo
    相对路径:会在代码所在的地方生成,比如:res/jay.txt  就会在你代码的目录下成jay.txt文件
   另外,由于路径名字符或者是抽象路径名的转换与生俱来就是依赖于系统的。比如在Unix系统中,绝对路径名的前缀总是“/”,然而在Windows系统中,绝对路径名的前缀总是”\”。
关于前缀的解决办法:
例1:在Windows中,路劲名为D:\Program Files
在java程序中,必须将”\”转换为”/”或者”\\”,比如:D:/Program Files或者D:\\Program Files
 
如果想让程序跨平台的话,由于Linux中是”/”,而Windows中是”\”,我们可以使用File提供的常量字符串File.separator,它能根据系统平台的不同,自动转换成”/”还是”\\”。

1.3 File的常见方法

1)判断文件或者目录是否存在:  exists()

2)判断是否为目录:   isDirectory()

3)判断是否为文件:   isFile()

4)判断文件是否可读:    canRead()

5)判断文件是否可写:    canWrite()

6)判断文件是否隐藏:    isHidden()

7)判断文件路径是否为绝对路径:  isAbsolute()

8)判断文件路径是否相同:  equals():返回true,false       

                                        compareTo():是否相等,相等返回0,小于返回负数,大于返回正数

9)获取文件的绝对路径:   getAbsolutePath()

10)获取文件名称:  getName()

11)获取文件大小:  length()

12)获取文件最后被修改的时间 :  lastModified()

13)获取文件的路径:   getPath()

14)获取文件的上层文件的目录:   getParent()

15)创建一个新文件:    createNewFile()

16)创建一个新目录:    mkdir()

17)删除文件或目录:  delete()

18)修改文件的名称:   renameTo(str)

19)修改文件为只读:  setReadOnly()

20)修改最后的修改时间:   setLastModified(long time)

二、源码分析

2.1 成员变量

所有成员变量如下:
下面列举一些比较关键的成员变量
// The FileSystem object representing the platform's local file system.
// 获取本地文件系统
private static final FileSystem fs = DefaultFileSystem.getFileSystem(); // 文件路径名
private final String path; // 标记文件路径是否无效
private transient PathStatus status = null; // The length of this abstract pathname's prefix, or zero if it has no prefix.
private final transient int prefixLength; /**
     * The system-dependent default name-separator character.  This field is
     * initialized to contain the first character of the value of the system
     * property <code>file.separator</code>.  On UNIX systems the value of this
     * field is <code>'/'</code>; on Microsoft Windows systems it is <code>'\\'</code>.
     *
*/
public static final char separatorChar = fs.getSeparator(); // The system-dependent path-separator character, represented as a string for convenience.
public static final String pathSeparator = "" + pathSeparatorChar;
1、成员变量 fs 是如何获取到本地文件系统的呢?
Windows平台下,所下载的JDK中,我们找到了WinNTFileSystem文件系统

Linux呢?因此,下了个Linux版本的JDK,解压,找到rt.jar。然后java/io目录中,找到了UnixFileSystem类。真相大白了!

其实是根据不同的平台,安装不同版本的JDK,根据平台下对应版本的JDK,加载本地文件系统。

解决了fs这个成员变量,那么separatorChar 这个成员变量就迎刃而解了。

2.2 构造函数

1、首先看看整体如下:

2、挑选比较有代表性的方法进行讲解
1) File(String pathname)
public File(String pathname) {
    if (pathname == null) {
        throw new NullPointerException();
    }
    this.path = fs.normalize(pathname);
    this.prefixLength = fs.prefixLength(this.path);
}

该构造方法主要是初始化了path、prefixLength两个成员变量,其中path通过WinNTFileSystem中normalize 公开方法将其规范化。

规范化后的好处,比如

public static void main(String[] args)
{
    File file = new File("d:/test.txt");
    System.out.println(file.getPath());   
}

File:

public String getPath() {
    return path;
}
输出结果:d:\test.txt
主要我们输入的是pathname = "d:/test.txt"  然而path得到的是"d:\test.txt” 。
2)File(File parent, String child)
public File(File parent, String child) {
    if (child == null) {
        throw new NullPointerException();
    }
    if (parent != null) {
        if (parent.path.equals("")) {
            this.path = fs.resolve(fs.getDefaultParent(),
                                   fs.normalize(child));
        } else {
            this.path = fs.resolve(parent.path,
                                   fs.normalize(child));
        }
    } else {
        this.path = fs.normalize(child);
    }
    this.prefixLength = fs.prefixLength(this.path);
}
其目的还是为path、prefixLength两个成员变量赋值。
其中,fs.resolve(parent.path,fs.normalize(child));目的就是在合理范围内拼接父与子路径

2.3 创建操作

  • createNewFile
  • createTempFile
  • mkdir

1)createNewFile()

public boolean createNewFile() throws IOException {
    // 1、检查是否有权限对该文件进行操作
    SecurityManager security = System.getSecurityManager();
    if (security != null) security.checkWrite(path);

// 2、检查文件路径是否有效
    if (isInvalid()) {
        throw new IOException("Invalid file path");
    }

// 3、在Windows中,调用WinNTFileSystem中createFileExclusively方法,该方法是调用系统底层方法。
    return fs.createFileExclusively(path);
}

 
2)mkdir()
// 此方法创建此抽象路径名的目录。
public boolean mkdir() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkWrite(path);
    }
    if (isInvalid()) {
        return false;
    }
    return fs.createDirectory(this);
}

2.4 删除操作

  • delete
  • deleteOnExit
1)delete()

public boolean delete() {
    // 1、权限检查
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkDelete(path);
    }

// 2、检查文件路径是否有效
    if (isInvalid()) {
        return false;
    }
   
    // 3、调用系统本地底层删除方法,
    // 不过在删除之前做了一些清理,cache.clear();prefixCache.clear();
    return fs.delete(this);
}

而deleteOnExit 一般用在删除临时文件。
注意:file.delete()或file.deleteOnExit()方法只能删除文件或空文件夹
2.5 获取文件操作
1)getAbsoluteFile()
// Returns the absolute form of this abstract pathname. Equivalent to new File(this.getAbsolutePath()). 
public File getAbsoluteFile() {
    String absPath = getAbsolutePath();
    return new File(absPath, fs.prefixLength(absPath));
}
2)getCanonicalFile()
// Returns the canonical form of this abstract pathname. Equivalent to new File(this.getCanonicalPath()). 
public File getCanonicalFile() throws IOException {
    String canonPath = getCanonicalPath();
    return new File(canonPath, fs.prefixLength(canonPath));
}
2.6 获取路径操作
1)getAbsolutePath()
// 此方法返回此抽象路径名的绝对路径名字符串。
public String getAbsolutePath() {
    return fs.resolve(this);
}
2)getCanonicalPath()
// 此方法返回此抽象路径名的规范路径名字符串。
public String getCanonicalPath() throws IOException {
    if (isInvalid()) {
        throw new IOException("Invalid file path");
    }
    return fs.canonicalize(fs.resolve(this));
}
3)getPath()
// 此方法此抽象路径名转换为一个路径名字符串。
// Converts this abstract pathname into a pathname string
// 此处pathname与File(String pathname)中pathname一致
public String getPath() {
    return path;
}

4)getParent()

// 此方法返回此抽象路径名的父路径名的字符串,或者null,如果此路径名没有指定父目录。
public String getParent() {
    // 查找最后分隔符的位置
     int index = path.lastIndexOf(separatorChar);
     if (index < prefixLength) {
         if ((prefixLength > 0) && (path.length() > prefixLength))
             return path.substring(0, prefixLength);
         return null;
     }
    // 获取最后分隔符之前的所有字符
     return path.substring(0, index);
}
 
由于File中的源码基本上调用系统底层的API,故不再介绍。
 
 
 
 
 
 
 
参考:

3、图解 Java IO : 一、File源码

java File详解的更多相关文章

  1. Java Annotation详解 理解和使用Annotation

    系统中用到了java注解: 查了一下如何使用注解,到底注解是什么: (1)创建方法:MsgTrace Java Class==> 在Create New Class中: name:输入MsgTr ...

  2. Java ClassLoad详解

    Java ClassLoad详解 类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一.它使得 Java 类可以被动态加载到 Java 虚拟机中并执行.类加载器从 JDK 1. ...

  3. Java NIO 详解(一)

    一.基本概念描述 1.1 I/O简介 I/O即输入输出,是计算机与外界世界的一个借口.IO操作的实际主题是操作系统.在java编程中,一般使用流的方式来处理IO,所有的IO都被视作是单个字节的移动,通 ...

  4. Java IO 详解

    Java IO 详解 初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正, ...

  5. Java集合详解3:Iterator,fail-fast机制与比较器

    Java集合详解3:Iterator,fail-fast机制与比较器 今天我们来探索一下LIterator,fail-fast机制与比较器的源码. 具体代码在我的GitHub中可以找到 https:/ ...

  6. Java ClassLoader详解(转载)

    Java ClassLoader详解 类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一.它使得 Java 类可以被动态加载到 Java 虚拟机中并执行.类加载器从 JDK ...

  7. Java内部类详解

    Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...

  8. 黑马----JAVA迭代器详解

    JAVA迭代器详解 1.Interable.Iterator和ListIterator 1)迭代器生成接口Interable,用于生成一个具体迭代器 public interface Iterable ...

  9. C++调用JAVA方法详解

    C++调用JAVA方法详解          博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...

随机推荐

  1. Xcode7如何添加pch文件

    我们在写项目的时候,大部分宏定义,头文件导入都在这里,Xcode6去掉Precompile Prefix Header的主要原因可能在于Prefix Header大大的增加了Build的时间.但是没有 ...

  2. JBoss7快速入门

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  3. 对Prepared Statement 是否可以防止 SQL Injection 的实验

    代码: import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; im ...

  4. 在android的spinner中,实现取VALUE值和TEXT值

    为了实现在android的spinner实现取VALUE值和TEXT值,我尝试过好些办法,在网上查的资料,都是说修改适配器,刚开始我也是通过修改适配器的方法来做的,但是如果一个activity有多个s ...

  5. WebService地址变成计算机名的解决办法

    WCF 4.0 has solved this issue in some instances with a new config option that use Request Headers: & ...

  6. 想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研

    想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研 http://blog.csdn.net/testing_is_believing/article/details/22 ...

  7. Java8的新特性

        Java 8主要新特性包括如下几点: 一.接口的默认方法和静态方法 Java 8版之前,接口只有抽象方法,而在Java 8,为接口新增了两种类型的方法. 第一种是默认方法:在Java 8中,可 ...

  8. HTML5规范的本地存储

    在HTML5 中定义了两种本地存储的,Web Storage 和本地数据库 SQL Database . 用来检查判断浏览器是否支持 Web Storage if(window.localStorag ...

  9. linux下设置mysql数据库字符集utf8

    mysql中文乱码解决方法:将mysql数据库编码统一utf8 查看数据库编码: show variables like 'character%'; 编辑/etc/my.cnf [mysql] def ...

  10. 转-----EasyCHM制作教程

    希望以后自己的笔记能够整理成 chm 格式的文档 制作过CHM帮助文件的同志们可能都遇到过以下两个问题: 1.制作好的CHM文件图像.公式不显示. 2.制作好的CHM文件在自己电脑上能显示,在别人电脑 ...