一、简介

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. 远程重启IIS服务

    方法一: $UserName = "administrator" $serverpass = "pass" $server = "10.4.19.60 ...

  2. [AngularJS] Introduction to angular-formly

    <!DOCTYPE html> <html> <head> <!-- Each of these scripts are the latest version ...

  3. android EditText输入变化事件详解

    editText.addTextChangedListener(new TextWatcher(){ public void afterTextChanged(Editable s) {    // ...

  4. C 栈实例

    就近匹配: 应用1:就近匹配 几乎所有的编译器都具有检测括号是否匹配的能力 如何实现编译器中的符号成对检测? #include <stdio.h> ][]; ]; p = a[]; ; 算 ...

  5. debian 系统备份

    tar -zcvpf /home/full-backup.tar.gz / --exclude=/mnt/* --exclude=/proc/* --exclude=/sys/* 这个命令是把根目录下 ...

  6. Apache的RewriteRule规则详细介绍

    R[=code](force redirect) 强制外部重定向 (rkyW z强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定, ...

  7. Regular Expressions --正则表达式官方教程

    http://docs.oracle.com/javase/tutorial/essential/regex/index.html This lesson explains how to use th ...

  8. Android Studio无法启动 打开, Android Studio gradle下载不了

    Google在2013年I/O大会上发布了Android Studio,AndroidStudio是一个基于IntelliJ思想的新的Android开发工具.下面介绍一下Android Studio安 ...

  9. iOS 图片加载框架- SDWebImage 解读

    在iOS的图片加载框架中,SDWebImage可谓是占据大半壁江山.它支持从网络中下载且缓存图片,并设置图片到对应的UIImageView控件或者UIButton控件.在项目中使用SDWebImage ...

  10. JS类型(1)_JS学习笔记(2016.10.02)

    js类型 js中的数据类型有undefined,boolean,number,string,null,object等6种,前5种为原始类型(基本类型),基本类型的访问是按值访问的,就是说你可以操作保存 ...