jdk1.8 java.io.File类源码阅读

public class File
    implements Serializable, Comparable<File>

实现了序列化和内部比较器Comparable.
内部比较方法

 public int compareTo(File pathname) {
        return fs.compare(this, pathname);
    }
 private static final FileSystem fs = DefaultFileSystem.getFileSystem();

fs属性是DefaultFileSystem.getFileSystem();返回的

class DefaultFileSystem {

    /**
     * Return the FileSystem object for Windows platform.
     */
    public static FileSystem getFileSystem() {
        return new WinNTFileSystem();
    }
}

默认是WinNTFileSystem

class WinNTFileSystem extends FileSystem 

WinNTFileSystem 继承的FileSystem,并且该类是修饰符是默认的,只能同一个包下才能访问.
ps:对比分析https://cloud.tencent.com/developer/article/1333744

abstract class FileSystem

FileSystem类简介https://blog.csdn.net/yaomingyang/article/details/79347284
FileSystem类方法详解:https://blog.csdn.net/yaomingyang/article/details/79351330(该类主要是对文件和路径的一些操作,该类是抽象的,需要不同系统下的类实现该方法,例如wind系统下的类为WinNTFileSystem )
compareTo(File pathname)方法为WinNTFileSystem 下的:

  @Override
    public int compare(File f1, File f2) {
        return f1.getPath().compareToIgnoreCase(f2.getPath());
    }

@Test

    @Test
    public void testFileCompare(){
        File file1 =new File("F:\\FileStudy\\test1.text");
        File file2 =new File("F:\\FileStudy\\test2.text");
        System.out.println(file1.compareTo(file2));
        File file3 =new File("F:\\FileStudy\\test2.text");
        File file4 =new File("F:\\FileStudy\\test1.text");
        System.out.println(file3.compareTo(file4));
        File file5 =new File("F:\\FileStudy\\test1.text");
        File file6 =new File("F:\\FileStudy\\test1.text");
        System.out.println(file5.compareTo(file6));
        File file7 =new File("F:\\FileStudy\\test1.text");
        File file8 =new File("F:\\FileStUdy\\TEST1.text");
        System.out.println(file7.compareTo(file8));
    }

输出结果:在这里插入图片描述
由上可以看出compareTo不区分大小写的比较,同一个文件返回0,不同文件返回<0,或者>0;

属性

/**
   * This abstract pathname's normalized pathname string. A normalized
   * pathname string uses the default name-separator character and does not
   * contain any duplicate or redundant separators.
   *
   * @serial
   */
  private final String path;

  /**
   * Enum type that indicates the status of a file path.
   */
  private static enum PathStatus { INVALID, CHECKED };

  /**
   * The flag indicating whether the file path is invalid.
   */
  private transient PathStatus status = null;

  /**
   * Check if the file has an invalid path. Currently, the inspection of
   * a file path is very limited, and it only covers Nul character check.
   * Returning true means the path is definitely invalid/garbage. But
   * returning false does not guarantee that the path is valid.
   *
   * @return true if the file path is invalid.
   */
  final boolean isInvalid() {
      if (status == null) {
          status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
                                                     : PathStatus.INVALID;
      }
      return status == PathStatus.INVALID;
  }

  /**
   * The length of this abstract pathname's prefix, or zero if it has no
   * prefix.
   */
  private final transient int prefixLength;

  /**
   * Returns the length of this abstract pathname's prefix.
   * For use by FileSystem classes.
   */
  int getPrefixLength() {
      return prefixLength;
  }

(1)
private final String path:注意用final修饰,当用final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后,就不能再被赋值了。
final关键字详解:https://www.cnblogs.com/dolphin0520/p/3736238.html

(2)
private static enum PathStatus { INVALID, CHECKED };
private transient PathStatus status = null;
定义了一个静态枚举类用于区分该文件的状态 INVALID:无效的 CHECKED:检查的

(3)
final boolean isInvalid():用于判读该文件是否非法类型
ps:注意成员变量和方法的修饰词


/**
     * 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>.
     *
     * @see     java.lang.System#getProperty(java.lang.String)
     */
    public static final char separatorChar = fs.getSeparator();

    /**
     * The system-dependent default name-separator character, represented as a
     * string for convenience.  This string contains a single character, namely
     * <code>{@link #separatorChar}</code>.
     */
    public static final String separator = "" + separatorChar;

separatorChar :fs.getSeparator();(fs属性上面已经解释)
依赖于系统的默认名称分隔符。此字段初始化为包含系统属性file.separator的值的第一个字符。在UNIX系统中,这个字段的值是’/’;在Microsoft Windows系统中,它是’\’。
getSeparator()是WinNTFileSystem类里面的方法

private final char slash;//斜杠符号
private final char altSlash;//与slash相反的斜杠
private final char semicolon;//分号
@Override
 public char getSeparator() {
     return slash;
 }

separator :把 char separatorChar 转换成字符串


    public static final char pathSeparatorChar = fs.getPathSeparator();

    /**
     * The system-dependent path-separator character, represented as a string
     * for convenience.  This string contains a single character, namely
     * <code>{@link #pathSeparatorChar}</code>.
     */
    public static final String pathSeparator = "" + pathSeparatorChar;

pathSeparatorChar:系统相关的路径分隔符。该字段初始化为包含系统属性path.separator的第一个字符。此字符用于分隔以路径列表形式给出的文件序列中的文件名。在UNIX系统中,这个字符是’:’;在Microsoft Windows系统中,它是“;”。
跟上面一样也是调用fs.getPathSeparator();

    @Override
    public char getPathSeparator() {
        return semicolon;
    }

构造方法

jdk1.8 文档:
在这里插入图片描述
源码的构造方法:
源码
volatile关键字解析:https://www.cnblogs.com/dolphin0520/p/3920373.html

方法

(1)public String getName();

   public String getName() {
       int index = path.lastIndexOf(separatorChar);
       if (index < prefixLength) return path.substring(prefixLength);
       return path.substring(index + 1);
   }

该方法返回由这个抽象路径名表示的文件或目录的名称。这只是路径名的名称序列中的最后一个名称。如果路径名的名称序列为空,则返回空字符串。
值得注意的是prefixLength的值只有0,1,2,3;对应的是pathname给定的文件路径是什么样子的,比如当pathname="" 时prefixLength=0,等等

(2)public String getParent();

    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);
    }

返回这个抽象路径名的父路径名字符串,如果这个路径名没有指定父目录,则返回null。
抽象路径名的父路径名由路径名前缀(如果有的话)和路径名名称序列中的每个名称(最后一个除外)组成。如果名称序列为空,则路径名不命名父目录。
@Test

    @Test
    public void getParent(){
        File file =new File("F:\\FileStudy\\test1.text");
        File file1 =new File("F:\\FileStudy");
        File file2 =new File("");
        System.out.println(file.getParent());
        System.out.println(file1.getParent());
        System.out.println(file2.getParent());

    }
    输出结果:F:\FileStudy;F:\;null

该方法的实现也是根据检索""出现的位置在与prefixLength 比较,得出父路劲的目录

(3) public File getParentFile();

    public File getParentFile() {
        String p = this.getParent();
        if (p == null) return null;
        return new File(p, this.prefixLength);
    }

返回这个抽象路径名的父路径名的抽象路径名,如果这个路径名没有指定父目录的名称,则返回null。
抽象路径名的父路径名由路径名前缀(如果有的话)和路径名名称序列中的每个名称(最后一个除外)组成。如果名称序列为空,则路径名不命名父目录。

该方法是调用上面的方法返回父路径的字符串,然后再利用构造函数构造File类型的值

(4)public boolean isAbsolute();

    public boolean isAbsolute() {
        return fs.isAbsolute(this);
    }

WinNTFileSystem 类中的isAbsolute方法

    @Override
    public boolean isAbsolute(File f) {
        int pl = f.getPrefixLength();
        return (((pl == 2) && (f.getPath().charAt(0) == slash))
                || (pl == 3));
    }

测试这个抽象路径名是否绝对。绝对路径名的定义依赖于系统。在UNIX系统中,如果路径名的前缀是“/”,那么它就是绝对路径名。在microsoftwindows系统中,如果路径名的前缀是驱动器说明符,后跟“\”,或者前缀是“\\”,则路径名是绝对的。
@Test

   @Test
    public void isAbsolute(){
        File file =new File("F:\\FileStudy\\test1.text");
        File file1 =new File("test1.text");
        File file2 =new File("");
        System.out.println(file.isAbsolute());
        System.out.println(file1.isAbsolute());
        System.out.println(file2.isAbsolute());

    }
输出结果:true;false;false

该方法也是跟prefixLength比较,得出是不是绝对路径

(5)
public String getAbsolutePath()

    public String getAbsolutePath() {
        return fs.resolve(this);
    }
WinNTFileSystem 类中的resolve方法:
  @Override
    public String resolve(File f) {
        String path = f.getPath();
        int pl = f.getPrefixLength();
        if ((pl == 2) && (path.charAt(0) == slash))
            return path;                        /* UNC */
        if (pl == 3)
            return path;                        /* Absolute local */
        if (pl == 0)
            return getUserPath() + slashify(path); /* Completely relative */
        if (pl == 1) {                          /* Drive-relative */
            String up = getUserPath();
            String ud = getDrive(up);
            if (ud != null) return ud + path;
            return up + path;                   /* User dir is a UNC path */
        }
        if (pl == 2) {                          /* Directory-relative */
            String up = getUserPath();
            String ud = getDrive(up);
            if ((ud != null) && path.startsWith(ud))
                return up + slashify(path.substring(2));
            char drive = path.charAt(0);
            String dir = getDriveDirectory(drive);
            String np;
            if (dir != null) {
                /* When resolving a directory-relative path that refers to a
                   drive other than the current drive, insist that the caller
                   have read permission on the result */
                String p = drive + (':' + dir + slashify(path.substring(2)));
                SecurityManager security = System.getSecurityManager();
                try {
                    if (security != null) security.checkRead(p);
                } catch (SecurityException x) {
                    /* Don't disclose the drive's directory in the exception */
                    throw new SecurityException("Cannot resolve path " + path);
                }
                return p;
            }
            return drive + ":" + slashify(path.substring(2)); /* fake it */
        }
        throw new InternalError("Unresolvable path: " + path);
    }

返回这个抽象路径名的绝对路径名字符串。
如果这个抽象路径名已经是绝对的,那么路径名字符串就会像getPath方法那样简单地返回。如果这个抽象路径名是空的抽象路径名,那么当前用户目录的路径名字符串将由系统属性user命名。dir,返回。否则,此路径名将以与系统相关的方式解析。在UNIX系统中,通过根据当前用户目录解析相对路径名,可以使其变为绝对路径名。在microsoftwindows系统中,相对路径名是绝对的,方法是根据路径名(如果有的话)命名的驱动器的当前目录解析它;如果不是,则根据当前用户目录解析。
@Test

    @Test
    public void getAbsolutePath(){
        File file =new File("F:\\FileStudy\\test1.text");
        File file1 =new File("test1.text");
        File file2 =new File("");
        System.out.println(file.getAbsolutePath());
        System.out.println(file1.getAbsolutePath());
        System.out.println(file2.getAbsolutePath());

    }
    输出结果:F:\FileStudy\test1.text;E:\java1.8Study\test1.text;E:\java1.8Study

该方法也是跟prefixLength比较,返回绝对路径的字符串,当该路径为相对路劲是返回的是:当前项目路径+pathname

(6)public File getAbsoluteFile();

    public File getAbsoluteFile() {
        String absPath = getAbsolutePath();
        return new File(absPath, fs.prefixLength(absPath));
    }

返回此抽象路径名的绝对形式。相当于新文件(this.getAbsolutePath)。
该方法跟上面的调用上面的方法,然后在调用构造函数,返回File类型

(7) public String getCanonicalPath() throws IOException;

  public String getCanonicalPath() throws IOException {
        if (isInvalid()) {
            throw new IOException("Invalid file path");
        }
        return fs.canonicalize(fs.resolve(this));
    }
  public File getCanonicalFile() throws IOException {
        String canonPath = getCanonicalPath();
        return new File(canonPath, fs.prefixLength(canonPath));
    }

返回这个抽象路径名的规范路径名字符串。

规范路径名是绝对的,也是唯一的。规范形式的精确定义依赖于系统。该方法首先在必要时将这个路径名转换为绝对形式,就像调用getAbsolutePath方法一样,然后以系统相关的方式将其映射到其惟一的形式。这通常涉及从路径名中删除“.”和“…”等冗余名称,解析符号链接(在UNIX平台上),并将驱动器字母转换为标准大小写(在Microsoft Windows平台上)。

表示现有文件或目录的每个路径名都有惟一的规范形式。表示不存在的文件或目录的每个路径名都有唯一的规范形式。不存在的文件或目录的路径名的规范形式可能与创建文件或目录后相同路径名的规范形式不同。类似地,现有文件或目录的路径名的规范形式可能与删除文件或目录后相同路径名的规范形式不同。

java中File类的getPath(),getAbsolutePath(),getCanonicalPath()区别:https://blog.51cto.com/handd/1173823
getCanonicalPath() 就是处理成规范模式:
比如.\test.txt 会转换成E:\java1.8Study\test1.text
getAbsolutePath():比如.\test.txt 会转换成E:\java1.8Study.\test1.text
@Test

   @Test
    public void getCanonicalPath() throws IOException {

        File file =new File(".\\test1.text");
        File file1 =new File(".\\test1.text");
        System.out.println(file.getAbsolutePath());
        System.out.println(file1.getCanonicalPath());
    }
输出结果:
E:\java1.8Study\.\test1.text
E:\java1.8Study\test1.text

(8) public URI toURI();

    public URI toURI() {
        try {
            File f = getAbsoluteFile();
            String sp = slashify(f.getPath(), f.isDirectory());
            if (sp.startsWith("//"))
                sp = "//" + sp;
            return new URI("file", null, sp, null);
        } catch (URISyntaxException x) {
            throw new Error(x);         // Can't happen
        }
    }
  private static String slashify(String path, boolean isDirectory) {
        String p = path;
        if (File.separatorChar != '/')
            p = p.replace(File.separatorChar, '/');
        if (!p.startsWith("/"))
            p = "/" + p;
        if (!p.endsWith("/") && isDirectory)
            p = p + "/";
        return p;
    }

构造一个表示此抽象路径名的file: URI。
URI的确切形式是依赖于系统的。 如果可以确定由此抽象路径名表示的文件是目录,则生成的URI将以斜杠结尾。

对于给定的抽象路径名f ,它是有保证的

new File( f .toURI()).equals( f .getAbsoluteFile())
只要原始的抽象路径名,URI和新的抽象路径名都在同一个Java虚拟机(可能不同的调用)中创建。 然而,由于抽象路径名的系统依赖性质,当将一个操作系统上的虚拟机中创建的8839929495048 URI转换为不同操作系统上的虚拟机中的抽象路径名时,此关系通常不成立。
请注意,当此抽象路径名表示UNC路径名时,UNC的所有组件(包括服务器名称组件)都将在URI路径中进行编码。 权限组件未定义,表示为null 。 所述Path类定义了toUri方法在所得的授权组成编码的服务器名称URI 。 toPath方法可用于获取表示此抽象路径名的Path 。
@Test

    @Test
    public void toURI() throws IOException {
        File file =new File("F:\\FileStudy\\test1.text");
        File file1 =new File("F:\\FileStudy");
        File file2 =new File("");
        System.out.println(file.toURI());
        System.out.println(file1.toURI());
        System.out.println(file2.toURI());
    }
 输出结果:
file:/F:/FileStudy/test1.text
file:/F:/FileStudy/
file:/E:/java1.8Study/

该方法主要把File转换成URL类型,然后对路径进行了加"/"处理

(9)public boolean canRead();

 public boolean canRead() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return false;
        }
        return fs.checkAccess(this, FileSystem.ACCESS_READ);
    }

WinNTFileSystem 类中的checkAccess方法,这是一个本地方法:检查由给定的抽象路径名表示的文件或目录是否可由该进程访问。第二个参数指定要检查的访问权限ACCESS_READ、ACCESS_WRITE或ACCESS_EXECUTE。如果访问被拒绝或出现I/O错误,则返回false

@Override
public native boolean checkAccess(File f, int access);

测试应用程序是否可以读取由这个抽象路径名表示的文件。在某些平台上,可以使用特权启动Java虚拟机,允许它读取标记为不可读的文件。因此,即使文件没有读权限,此方法也可能返回true。
@Test

    @Test
    public void canRead() {
        File file =new File("F:\\FileStudy\\test1.txt");//有该文件
        File file1 =new File("F:\\FileStudy\\test1.text");//没有该文件
        File file2 =new File("");
        System.out.println(file.canRead());
        System.out.println(file1.canRead());
        System.out.println(file2.canRead());
    }
    输出结果:
    true
	false
	false

由上可以看出错误文件和""都返回false,其余有可读属性返回true

(10)public boolean canWrite();

  public boolean canWrite() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
        }
        if (isInvalid()) {
            return false;
        }
        return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
    }

测试应用程序是否可以修改这个抽象路径名表示的文件。在某些平台上,可以使用特权启动Java虚拟机,允许它修改标记为只读的文件。因此,即使文件被标记为只读,此方法也可能返回true。
@Test

    @Test
  public void canWrite() {
      File file =new File("F:\\FileStudy\\test1.txt");//设置成可读
      File file1 =new File("F:\\FileStudy\\test1.text");//错误文件
      File file2 =new File("");
      File file3 =new File("F:\\FileStudy\\test2.txt");//没有设置成可读
      System.out.println(file.canWrite());
      System.out.println(file1.canWrite());
      System.out.println(file2.canWrite());
      System.out.println(file3.canWrite());
  }
  输出结果:
  false
  false
  false
  true

由上可以看出,文件设置成可读,错误文件和""都返回false,没有设置的返回true

(11)public boolean exists();

    public boolean exists() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return false;
        }
        return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
    } 

WinNTFileSystem 类中的getBooleanAttributes方法:为指定的抽象路径名表示的文件或目录返回简单的布尔属性,如果不存在或出现其他I/O错误,则返回0。

    @Override
   public native int getBooleanAttributes(File f);

测试由这个抽象路径名表示的文件或目录是否存在。
@Test

    @Test
   public void exists() {
       File file =new File("F:\\FileStudy\\test1.txt");//设置成可读
       File file1 =new File("F:\\FileStudy\\test1.text");//错误文件
       File file2 =new File("");
       File file3 =new File("F:\\FileStudy\\test2.txt");//没有设置成可读
       File file4 =new File("F:\\FileStudy");//目录
       System.out.println(file.exists());
       System.out.println(file1.exists());
       System.out.println(file2.exists());
       System.out.println(file3.exists());
       System.out.println(file4.exists());
   }
   输出结果:
true
false
false
true
true    

由上可以看出,也是调用WinNTFileSystem 类中的本地方法进行判断是否存在该文件或者目录,存在返回true,不存在返回false

(12)public boolean isDirectory();

    public boolean isDirectory() {
       SecurityManager security = System.getSecurityManager();
       if (security != null) {
           security.checkRead(path);
       }
       if (isInvalid()) {
           return false;
       }
       return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
               != 0);
   }

测试由这个抽象路径名表示的文件是否是一个目录。
如果需要将I/O异常与文件不是目录的情况区分开,或者同时需要同一文件的多个属性,则需要文件。可以使用readAttributes方法。
@Test

    @Test
    public void isDirectory() {
        File file =new File("F:\\FileStudy\\test1.txt");//设置成可读
        File file1 =new File("F:\\FileStudy\\test1.text");//错误文件
        File file2 =new File("");
        File file3 =new File("F:\\FileStudy\\test2.txt");//没有设置成可读
        File file4 =new File("F:\\FileStudy");//目录

        System.out.println(file.isDirectory());
        System.out.println(file1.isDirectory());
        System.out.println(file2.isDirectory());
        System.out.println(file3.isDirectory());
        System.out.println(file4.isDirectory());
    }
    输出结果:
false
false
false
false
true

判断文件是不是目录,由上可以看出也是调用WinNTFileSystem 类中的getBooleanAttributes方法,最后 & FileSystem.BA_DIRECTORY常量进行判断是否是目录.文件或者错误文件都返回false,只有存在目录的返回false

(13)public boolean isFile();

    public boolean isFile() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return false;
        }
        return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
    }

测试由这个抽象路径名表示的文件是否是一个普通文件。如果文件不是目录,并且满足其他与系统相关的条件,那么它就是正常的。Java应用程序创建的任何非目录文件都保证是正常的文件。
如果需要将I/O异常与文件不是普通文件的情况区分开来,或者同时需要同一文件的多个属性,则使用文件。可以使用readAttributes方法。
@Test

    @Test
    public void isFile() {
        File file =new File("F:\\FileStudy\\test1.txt");//设置成可读
        File file1 =new File("F:\\FileStudy\\test1.text");//错误文件
        File file2 =new File("");
        File file3 =new File("F:\\FileStudy\\test2.txt");//没有设置成可读
        File file4 =new File("F:\\FileStudy");//目录

        System.out.println(file.isFile());
        System.out.println(file1.isFile());
        System.out.println(file2.isFile());
        System.out.println(file3.isFile());
        System.out.println(file4.isFile());
    }
    输出结果:
true
false
false
true
false

跟isDirectory()方法一样也是& FileSystem.BA_REGULAR常量去判断是否为文件.
只有该文件是一个文件而不是目录和假文件才返回true,其余返回false

(14)public boolean isHidden();

    public boolean isHidden() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return false;
        }
        return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
    }

测试由这个抽象路径名命名的文件是否为隐藏文件。隐藏的确切定义依赖于系统。在UNIX系统中,如果文件的名称以句点字符(’.’)开头,则认为该文件是隐藏的。在microsoftwindows系统中,如果文件系统中已将其标记为隐藏文件,则认为该文件已被隐藏。
@Test

    @Test
    public void isHidden() {
        File file =new File("F:\\FileStudy\\test1.txt");//设置成隐藏
        File file1 =new File("F:\\FileStudy\\test1.text");//错误文件
        File file2 =new File("");
        File file3 =new File("F:\\FileStudy\\test2.txt");//没有设置成可读
        File file4 =new File("F:\\FileStudy");//目录

        System.out.println(file.isHidden());
        System.out.println(file1.isHidden());
        System.out.println(file2.isHidden());
        System.out.println(file3.isHidden());
        System.out.println(file4.isHidden());
    }
   输出结果:
true
false
false
false
false

跟上面的几个方法实现的原理一样.

(15)public long lastModified();

    public long lastModified() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return 0L;
        }
        return fs.getLastModifiedTime(this);
    }

返回由这个抽象路径名表示的文件最后修改的时间。

如果需要将I/O异常与返回0L的情况区分开,或者在同一时间需要同一文件的多个属性,或者需要最后一次访问的时间或创建时间,则需要文件。可以使用readAttributes方法。
@Test

    @Test
    public void lastModified() {
        File file =new File("F:\\FileStudy\\test1.txt");//设置成隐藏
        File file1 =new File("F:\\FileStudy\\test1.text");//错误文件
        File file2 =new File("");
        File file3 =new File("F:\\FileStudy\\test2.txt");//没有设置成可读
        File file4 =new File("F:\\FileStudy");//目录

        System.out.println(file.lastModified());
        System.out.println(file1.lastModified());
        System.out.println(file2.lastModified());
        System.out.println(file3.lastModified());
        System.out.println(file4.lastModified());
    }
    输出结果:
1581419351429
0
0
1581419351429
1581419386036

该方法也是调用WinNTFileSystem 类本地方法getLastModifiedTime(File f),注意返回的是long的类型,错误文件直接返回0.

(16) public long length();

    public long length() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return 0L;
        }
        return fs.getLength(this);
    }

返回由这个抽象路径名表示的文件长度。如果此路径名表示目录,则返回值未指定。
如果需要将I/O异常与返回0L的情况区分开,或者同时需要相同文件的多个属性,则需要文件。可以使用readAttributes方法。
@Test

    @Test
    public void length() {
        File file =new File("F:\\FileStudy\\test1.txt");//设置成隐藏
        File file1 =new File("F:\\FileStudy\\test1.text");//错误文件
        File file2 =new File("");
        File file3 =new File("F:\\FileStudy\\test2.txt");//没有设置成可读
        File file4 =new File("F:\\FileStudy");//目录

        System.out.println(file.length());
        System.out.println(file1.length());
        System.out.println(file2.length());
        System.out.println(file3.length());
        System.out.println(file4.length());
    }
    输出结果:
0
0
0
14
0

由上可以看出,如果是空文件,假文件和目录都返回0,有内容的文件返回文件大小,大小用字节表示.也是调用WinNTFileSystem 类本地方法public native long getLength(File f);

(17)public boolean createNewFile() throws IOException;

   public boolean createNewFile() throws IOException {
        SecurityManager security = System.getSecurityManager();
        if (security != null) security.checkWrite(path);
        if (isInvalid()) {
            throw new IOException("Invalid file path");
        }
        return fs.createFileExclusively(path);
    }

当且仅当具有此名称的文件尚不存在时,原子地创建一个由此抽象路径名命名的新空文件。对于可能影响文件的所有其他文件系统活动来说,检查文件是否存在以及如果文件不存在则创建文件是一个单独的原子操作。
注意:这个方法不能用于文件锁定,因为产生的协议不能可靠地工作。应该使用FileLock工具。
@Test

    @Test
    public void createNewFile() throws IOException {
        File file =new File("F:\\FileStudy\\test1.txt");//设置成隐藏
        File file1 =new File("F:\\FileStudy\\te1.text");//错误文件
        File file3 =new File("F:\\FileStudy\\test2.txt");//没有设置成可读
        File file4 =new File("F:\\FileStudy");//目录
        File file5 =new File("F:\\FilStudy");//不存在该目录

        File file2 =new File("");

        System.out.println(file.createNewFile());
        System.out.println(file1.createNewFile());
        System.out.println(file3.createNewFile());
        System.out.println(file4.createNewFile());
        System.out.println(file5.createNewFile());
        System.out.println(file2.createNewFile());
    }
输出结果:
false
true
false
false
true
java.io.IOException: 系统找不到指定的路径。

该方法也是调用WinNTFileSystem 类本地方法public native boolean createFileExclusively(String path) throws IOException;当存在该文件时,直接返回false;不存在该文件并且路径正确则会创建该文件的空文件;当不存在该目录时创建没有后缀的文件,比如file5如下图;
在这里插入图片描述
不存在该路径时抛出IOException异常.

(18)public boolean delete();

  public boolean delete() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkDelete(path);
        }
        if (isInvalid()) {
            return false;
        }
        return fs.delete(this);
    }

WinNTFileSystem 类public boolean delete(File f);

  @Override
    public boolean delete(File f) {
        // Keep canonicalization caches in sync after file deletion
        // and renaming operations. Could be more clever than this
        // (i.e., only remove/update affected entries) but probably
        // not worth it since these entries expire after 30 seconds
        // anyway.
        cache.clear();
        prefixCache.clear();
        return delete0(f);
    }

    private native boolean delete0(File f);

删除由这个抽象路径名表示的文件或目录。如果这个路径名表示一个目录,那么该目录必须为空才能删除。

请注意java.nio.文件。Files类定义删除方法,以便在无法删除文件时抛出IOException。这对于错误报告和诊断为什么文件不能删除非常有用。
@Test

    @Test
    public void delete() throws IOException {
        File file =new File("F:\\FileStudy\\test1.txt");//设置成隐藏
        File file1 =new File("F:\\FileStudy\\te1.text");//错误文件
        File file5 =new File("F:\\FilStudy");//不存在该目录
        File file2 =new File("");

        System.out.println(file.delete());
        System.out.println(file1.delete());

        System.out.println(file5.delete());
        System.out.println(file2.delete());
    }
输出结果:
true
true
true
false

由上可以看出,删除该文件也是掉WinNTFileSystem类的本地方法,但是调用之前先清除缓存里面的缓存值,然后在调用本地方法. 当存在该文件或者目录直接删除返回true,不存在或者为""返回false.

(19)public void deleteOnExit();

   public void deleteOnExit() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkDelete(path);
        }
        if (isInvalid()) {
            return;
        }
        DeleteOnExitHook.add(path);
    }

请求在虚拟机终止时删除由此抽象路径名表示的文件或目录。 文件(或目录)按注册的相反顺序进行删除。 调用此方法删除已注册删除的文件或目录无效。 将仅针对Java语言规范定义的虚拟机的正常终止而尝试删除。
一旦请求删除,就无法取消请求。 因此,该方法应谨慎使用。
注意:此方法不应用于文件锁定,因为生成的协议不能使其可靠地工作。 应该使用FileLock设施。
该方法和DeleteOnExitHook类详解:https://blog.csdn.net/10km/article/details/51822560
file.delete()与file.deleteOnExit()的区别:https://blog.csdn.net/asty9000/article/details/80488350

(20) public String[] list();
函数式编程可以学习.

  public String[] list() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return null;
        }
        return fs.list(this);
    }
 public String[] list(FilenameFilter filter) {
        String names[] = list();
        if ((names == null) || (filter == null)) {
            return names;
        }
        List<String> v = new ArrayList<>();
        for (int i = 0 ; i < names.length ; i++) {
            if (filter.accept(this, names[i])) {
                v.add(names[i]);
            }
        }
        return v.toArray(new String[v.size()]);
    }

WinNTFileSystem 类本地方法public native String[] list(File f):文件系统列出用给定的抽象路径名表示的目录的元素。如果成功,返回命名目录元素的字符串数组;否则,返回null。

    @Override
    public native String[] list(File f);

public String[] list():
返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。
如果此抽象路径名不表示目录,则此方法返回null 。 否则返回一个字符串数组,一个用于目录中的每个文件或目录。 表示目录本身和目录的父目录的名称不包括在结果中。 每个字符串都是一个文件名,而不是完整的路径。

不保证结果数组中的名称字符串将以任何特定的顺序出现; 他们不是特别保证按字母顺序出现。

请注意, Files类定义了newDirectoryStream方法来打开目录并遍历目录中文件的名称。 在使用非常大的目录时,这可能会减少资源,并且在使用远程目录时可能会更加灵活。

结果
一组字符串,命名由此抽象路径名表示的目录中的文件和目录。 如果目录为空,则该数组将为空。 如果此抽象路径名不表示目录,或返回I / O错误,则返回null 。
异常
SecurityException - 如果安全管理器存在,并且其 SecurityManager.checkRead(String)方法拒绝对目录的读取访问

public String[] list(FilenameFilter filter):
返回一个字符串数组,命名由此抽象路径名表示的目录中满足指定过滤器的文件和目录。 该方法的行为与list()方法的行为相同,只是返回的数组中的字符串必须满足过滤器。 如果给定的filter是null那么所有的名字都被接受。 否则,一个名称满足过滤器,当且仅当值true当结果FilenameFilter.accept(File, String)滤波器的方法是在此抽象路径名和在于其表示目录中的文件或目录的名称调用。
参数
filter - 文件名过滤器
结果
一组字符串,命名由该抽象路径名表示的目录中由指定的filter接受的文件和filter 。 如果目录为空,或者过滤器没有接受名称,则该数组将为空。 如果此抽象路径名不表示目录,或返回I / O错误,则返回null 。
异常
SecurityException - 如果安全管理器存在,并且其 SecurityManager.checkRead(String)方法拒绝对目录的读取访问
@Test

    @Test
    public void list() throws IOException {
        File file =new File("F:\\FileStudy\\test1.txt");//设置成隐藏
        File file1 =new File("F:\\FileStudy\\te1.text");//错误文件
        File file5 =new File("F:\\FileStudy");//目录
        File file6 =new File("F:\\FilStudy");//不存在该目录

        File file2 =new File("");

        System.out.println(Arrays.toString(file.list()));
        System.out.println(Arrays.toString(file1.list()));
        System.out.println(Arrays.toString(file5.list()));
        System.out.println(Arrays.toString(file6.list()));
        System.out.println(Arrays.toString(file2.list()));
    }
输出结果:
null
null
[test1.text, test2.txt, tet1.text]
null
null

由上可以看出,如果当前的文件不是目录或者是不存在的目录和文件则返回null,如果存在则输出该目录下的文件名.
@Test

    @Test
    public void listFilenameFilter() throws IOException {

        File file5 = new File("F:\\FileStudy");//目录
        File file6 = new File("F:\\FilStudy");//不存在该目录
        System.out.println(Arrays.toString(file5.list((v, t) -> {
            if (v.equals(new File("F:\\FileStudy"))) return true;
            return false;
        })));
        System.out.println(Arrays.toString(file5.list((v, t) -> {
            if (v.equals(new File("F:\\FileStudy"))&& !t.equals("test1.text")) return true;
            return false;
        })));
        System.out.println(Arrays.toString(file6.list((v, t) -> {
            if (v.equals(new File("F:\\FileStudy"))) return true;
            return false;
        })));
    }
输出结果:
[test1.text, test2.txt, tet1.text]
[test2.txt, tet1.text]
null

跟上面的方法一样,只是添加了一个参数FilenameFilter filter用于过滤,该参数可以使用lambada表达式写,函数式编程.

(21) public File[] listFiles();

    public File[] listFiles() {
        String[] ss = list();
        if (ss == null) return null;
        int n = ss.length;
        File[] fs = new File[n];
        for (int i = 0; i < n; i++) {
            fs[i] = new File(ss[i], this);
        }
        return fs;
    }
   public File[] listFiles(FilenameFilter filter) {
        String ss[] = list();
        if (ss == null) return null;
        ArrayList<File> files = new ArrayList<>();
        for (String s : ss)
            if ((filter == null) || filter.accept(this, s))
                files.add(new File(s, this));
        return files.toArray(new File[files.size()]);
    }

这两个方法是调用上面的方法,然后在利用构造方法转换成File类型.

    public File[] listFiles(FileFilter filter) {
        String ss[] = list();
        if (ss == null) return null;
        ArrayList<File> files = new ArrayList<>();
        for (String s : ss) {
            File f = new File(s, this);
            if ((filter == null) || filter.accept(f))
                files.add(f);
        }
        return files.toArray(new File[files.size()]);
    }

该方法跟上面的方法一样,只是参数变成FileFilter filter,查看该源码可以看出

@FunctionalInterface
public interface FileFilter {

    /**
     * Tests whether or not the specified abstract pathname should be
     * included in a pathname list.
     *
     * @param  pathname  The abstract pathname to be tested
     * @return  <code>true</code> if and only if <code>pathname</code>
     *          should be included
     */
    boolean accept(File pathname);
}

该过滤器中的方法只有一个参数File pathname
@Test

    @Test
    public void listFiles() throws IOException {
        File file5 = new File("F:\\FileStudy");//目录
        File[] files = file5.listFiles(
                v -> {
                    if (v.equals(new File("F:\\FileStudy\\test1.text"))) return true;
                    return false;
                }
        );
        System.out.println(Arrays.toString(files));
    }
    输出结果:
    [F:\FileStudy\test1.text]

跟上面的方法一样,只是一个是两个参数的过滤器,一个一个参数的过滤器,参数类型也不同,一个参数的类型File类型.

(22)
public boolean mkdir():创建由此抽象路径名命名的目录。
public boolean mkdirs():创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录。 请注意,如果此操作失败,它可能已成功创建一些必需的父目录

   public boolean mkdir() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
        }
        if (isInvalid()) {
            return false;
        }
        return fs.createDirectory(this);
    }
    -----------------------------------------------------------------
    public boolean mkdirs() {
        if (exists()) {
            return false;
        }
        if (mkdir()) {
            return true;
        }
        File canonFile = null;
        try {
            canonFile = getCanonicalFile();
        } catch (IOException e) {
            return false;
        }

        File parent = canonFile.getParentFile();
        return (parent != null && (parent.mkdirs() || parent.exists()) &&
                canonFile.mkdir());
    }

WinNTFileSystem 类本地方法public native boolean createDirectory(File f);

   @Override
   public native boolean createDirectory(File f);

值得注意的是mkdirs()方法里面采用了递归,先是判断该目录是否存在,不存在创建该目录,可能出现失败,失败后获取该规范形式的File,然后在执行这个条件
(parent != null && (parent.mkdirs() || parent.exists()) && canonFile.mkdir())
返回true表示成功

(23)public boolean renameTo(File dest);

    public boolean renameTo(File dest) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
            security.checkWrite(dest.path);
        }
        if (dest == null) {
            throw new NullPointerException();
        }
        if (this.isInvalid() || dest.isInvalid()) {
            return false;
        }
        return fs.rename(this, dest);
    }

WinNTFileSystem 类的rename(File f1, File f2):

    @Override
    public boolean rename(File f1, File f2) {
        // Keep canonicalization caches in sync after file deletion
        // and renaming operations. Could be more clever than this
        // (i.e., only remove/update affected entries) but probably
        // not worth it since these entries expire after 30 seconds
        // anyway.
        cache.clear();
        prefixCache.clear();
        return rename0(f1, f2);
    }

    private native boolean rename0(File f1, File f2);

public boolean renameTo(File dest)
重命名由此抽象路径名表示的文件。
该方法的行为的许多方面固有地依赖于平台:重命名操作可能无法将文件从一个文件系统移动到另一个文件系统,它可能不是原子的,如果具有目标抽象路径名的文件可能无法成功已经存在。 应始终检查返回值,以确保重命名操作成功。
请注意, Files类定义了以独立于平台的方式移动或重命名文件的move方法。
参数
dest - 命名文件的新抽象路径名
结果
true当且仅当重命名成功; false否则
异常
SecurityException - 如果安全管理器存在,并且其 SecurityManager.checkWrite(java.lang.String)方法拒绝对旧的或新的路径名的写入访问
NullPointerException - 如果参数 dest是 null
@Test

    @Test
    public void renameTo() {
        File file = new File("F:\\FileStudy\\test1.text");//存在的文件
        File file1 = new File("F:\\FileStudy\\test1.ext");//不存的文件
        File file2 = new File("");//为空
        System.out.println(file.renameTo(new File("F:\\FileStudy\\test1.txt")));
        System.out.println(file1.renameTo(new File("F:\\FileStudy\\test1.xt")));
        System.out.println(file2.renameTo(new File("F:\\FileStudy\\test1.t")));
        System.out.println(file.renameTo(null));
    }
输出结果:
true
false
false
java.lang.NullPointerException

第一个修改成功:
在这里插入图片描述
由上可知,该方法也是调用WinNTFileSystem类中的本地方法,只是在调用之前,清楚了缓存表中的数据,然后在调用本地方法.而File类中做了一些参数校验,是否可写,是否有效,dest是否为null.
看@Test可以看出,当存在该文件则会重命名成功返回true,不存在返回false修改不成功.当dest为null,抛出控制针异常.

(24)Set*类方法:该类方法主要设置可读可写和一些权限,都是调用WinNTFileSystem类中的本地方法,jdk1.8文档解释:

  1. public boolean setExecutable(boolean executable)
    为此抽象路径名设置所有者的执行权限的便利方法。 在某些平台上,可能会启动具有特殊权限的Java虚拟机,以允许其执行未标记为可执行文件。
    调用此方法的形式为file.setExcutable(arg)的行为方式与调用完全相同
    file.setExecutable(arg, true)
    参数
    executable - 如果true ,设置访问权限允许执行操作; 如果false不允许执行操作
    结果
    true当且仅当操作成功。 如果用户没有权限更改此抽象路径名的访问权限,操作将失败。 如果executable是false并且底层文件系统没有实现执行权限,那么操作将失败。
    异常
    SecurityException - 如果存在安全管理员,并且其 SecurityManager.checkWrite(java.lang.String)方法拒绝对文件的写入访问

  1. public boolean setExecutable(boolean executable,boolean ownerOnly)
    设置该抽象路径名的所有者或每个人的执行权限。 在某些平台上,可能会启动具有特殊权限的Java虚拟机,以允许其执行未标记为可执行文件。
    Files类定义了对文件属性(包括文件权限)进行操作的方法。 当需要更精细的文件权限操作时,可以使用这种方法。
    参数
    executable - 如果true ,设置访问权限允许执行操作; 如果false不允许执行操作
    ownerOnly - 如果true ,则执行权限仅适用于所有者的执行权限; 否则适用于所有人。 如果底层文件系统无法区分所有者的执行权限与其他人的执行权限,则该权限将适用于所有人,不管该值。
    结果
    true当且仅当操作成功。 如果用户没有权限更改此抽象路径名的访问权限,操作将失败。 如果executable是false并且底层文件系统没有实现执行权限,那么操作将失败。
    异常
    SecurityException - 如果安全管理器存在,并且其 SecurityManager.checkWrite(java.lang.String)方法拒绝对该文件的写访问
    ps:个人理解可以执行的文件为每个人设置执行权限,列如wind下.exe后缀文件

  1. public boolean setLastModified(long time)
    设置由此抽象路径名命名的文件或目录的最后修改时间。
    所有平台都支持文件修改时间到最近的秒数,但有些则提供更高的精度。 参数将被截断以适应支持的精度。 如果操作成功,并且不会对文件进行干预操作,则下一次调用lastModified()方法将返回传递给此方法的(可能截断的) time参数。
    参数
    time - 自上个世纪(1970年1月1日00:00:00 GMT)以来,以毫秒计
    结果
    true当且仅当操作成功; false否则
    异常
    IllegalArgumentException - 如果参数为负数
    SecurityException - 如果安全管理器存在,并且其 SecurityManager.checkWrite(java.lang.String)方法拒绝对命名文件的写入访问

  1. public boolean setReadable(boolean readable)
    一种方便的方法来设置所有者对此抽象路径名的读取权限。 在某些平台上,可以使用特殊权限启动Java虚拟机,以允许它读取标记为不可读的文件。
    调用此方法的形式为file.setReadable(arg)的行为方式与调用完全相同
    file.setReadable(arg, true)
    参数
    readable - 如果true ,设置访问权限允许读操作; 如果false不允许读操作
    结果
    true当且仅当操作成功。 如果用户没有权限更改此抽象路径名的访问权限,操作将失败。 如果readable是false ,并且底层文件系统没有实现读取权限,则操作将失败。
    异常
    SecurityException - 如果安全管理器存在,并且其 SecurityManager.checkWrite(java.lang.String)方法拒绝对该文件的写入访问

  1. public boolean setReadable(boolean readable,
    boolean ownerOnly)
    设置此抽象路径名的所有者或每个人的读取权限。 在某些平台上,可以使用特殊权限启动Java虚拟机,以允许它读取标记为不可读的文件。
    Files类定义了对文件属性(包括文件权限)进行操作的方法。 当需要更精细的文件权限操作时,可以使用这种方法。
    参数
    readable - 如果true ,设置访问权限允许读操作; 如果false不允许读操作
    ownerOnly - 如果true ,读权限仅适用于所有者的读权限; 否则适用于所有人。 如果底层文件系统无法区分所有者的读取权限与其他用户的读取权限,则该权限将适用于所有人,不管该值如何。
    结果
    true当且仅当操作成功。 如果用户没有权限更改此抽象路径名的访问权限,操作将失败。 如果readable是false并且底层文件系统没有实现读取权限,则操作将失败。
    异常
    SecurityException - 如果存在安全管理员,并且其 SecurityManager.checkWrite(java.lang.String)方法拒绝对文件的写入访问

  1. public boolean setWritable(boolean writable)
    一种方便的方法来设置所有者对此抽象路径名的写入权限。 在某些平台上,可能会启动具有特殊权限的Java虚拟机,允许它修改不允许写入操作的文件。
    调用此方法的形式为file.setWritable(arg)的行为方式与调用完全相同
    file.setWritable(arg, true)
    参数
    writable - 如果true ,设置访问权限允许写操作; 如果false不允许写操作
    结果
    true当且仅当操作成功。 如果用户没有权限更改此抽象路径名的访问权限,操作将失败。
    异常
    SecurityException - 如果安全管理器存在,并且其 SecurityManager.checkWrite(java.lang.String)方法拒绝对文件的写入访问

  1. public boolean setReadable(boolean readable,
    boolean ownerOnly)
    设置此抽象路径名的所有者或每个人的读取权限。 在某些平台上,可以使用特殊权限启动Java虚拟机,以允许它读取标记为不可读的文件。
    Files类定义了对文件属性(包括文件权限)进行操作的方法。 当需要更精细的文件权限操作时,可以使用这种方法。
    参数
    readable - 如果true ,设置访问权限允许读操作; 如果false不允许读操作
    ownerOnly - 如果true ,读权限仅适用于所有者的读权限; 否则适用于所有人。 如果底层文件系统无法区分所有者的读取权限与其他用户的读取权限,则该权限将适用于所有人,不管该值如何。
    结果
    true当且仅当操作成功。 如果用户没有权限更改此抽象路径名的访问权限,操作将失败。 如果readable是false并且底层文件系统没有实现读取权限,则操作将失败。
    异常
    SecurityException - 如果存在安全管理员,并且其 SecurityManager.checkWrite(java.lang.String)方法拒绝对文件的写入访问

(25) public static File[] listRoots():

public static File[] listRoots() {
        return fs.listRoots();
    }

WinNTFileSystem类中的listRoots()

    @Override
    public File[] listRoots() {
        int ds = listRoots0();
        int n = 0;
        for (int i = 0; i < 26; i++) {
            if (((ds >> i) & 1) != 0) {
                if (!access((char)('A' + i) + ":" + slash))
                    ds &= ~(1 << i);
                else
                    n++;
            }
        }
        File[] fs = new File[n];
        int j = 0;
        char slash = this.slash;
        for (int i = 0; i < 26; i++) {
            if (((ds >> i) & 1) != 0)
                fs[j++] = new File((char)('A' + i) + ":" + slash);
        }
        return fs;
    }

    private static native int listRoots0();

public static File[] listRoots()
列出可用的文件系统根。
一个特定的Java平台可以支持零个或多个分层组织的文件系统。 每个文件系统都有一个root目录,从该目录可以访问该文件系统中的所有其他文件。 例如,Windows平台具有每个活动驱动器的根目录; UNIX平台有一个根目录,即"/" 。 可用文件系统根的集合受到各种系统级操作的影响,例如插入或弹出可移动介质以及断开或卸载物理或虚拟磁盘驱动器。

此方法返回一个File对象的数组,它们表示可用文件系统根的根目录。 确保本地机器上物理存在的任何文件的规范路径名将以此方法返回的其中一个根源开始。

驻留在某个其他机器上并通过远程文件系统协议(如SMB或NFS)访问的文件的规范路径名可能或可能不以此方法返回的根目录之一开始。 如果远程文件的路径名在语法上与本地文件的路径名无法区分,那么它将以此方法返回的其中一个根开始。 因此,例如, File对象表示在Windows平台的映射的网络驱动器的根目录下将通过该方法返回,而File含有UNC路径名的对象将不通过该方法来返回。

与此类中的大多数方法不同,此方法不会抛出安全异常。 如果安全管理器存在,并且其SecurityManager.checkRead(String)方法拒绝对特定根目录的读取访问,则该目录将不会显示在结果中。

结果
一组File对象表示可用的文件系统根,或null如果无法确定根组。 如果没有文件系统根,数组将为空。
@Test

 @Test
    public void listRoots() {
        System.out.println(Arrays.toString(File.listRoots()));
    }
    输出结果:
    [C:\, D:\, E:\, F:\]

该方法是一个静态方法,返回该系统所有的根路径,如上.注意返回类型为File

(26) public long getTotalSpace();

    public long getTotalSpace() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
            sm.checkRead(path);
        }
        if (isInvalid()) {
            return 0L;
        }
        return fs.getSpace(this, FileSystem.SPACE_TOTAL);
    }

WinNTFileSystem类中的getSpace(File f, int t)

  @Override
    public long getSpace(File f, int t) {
        if (f.exists()) {
            return getSpace0(f, t);
        }
        return 0;
    }

    private native long getSpace0(File f, int t);

public long getTotalSpace()
通过此抽象路径名返回分区 named的大小。
结果
分区的大小(以字节为单位)或 0L(如果此抽象路径名未命名分区)
异常
SecurityException - 如果安全管理器已经安装,否认RuntimePermission (“getFileSystemAttributes”)或其SecurityManager.checkRead(String)方法拒绝对此抽象路径名命名的文件的读访问权限
@Test

    @Test
    public void getTotalSpace() {
        File file = new File("F:\\FileStudy\\test1.txt");//存在的文件
        File file1 = new File("F:\\FileStudy\\test1.t1xt");//不存在该文件
        File file2 = new File("F:\\FileStudy");//目录
        File file3 = new File("F:");//根目录

        System.out.println(file.getTotalSpace());
        System.out.println(file1.getTotalSpace());
        System.out.println(file2.getTotalSpace());
        System.out.println(file3.getTotalSpace());
    }
输出结果:
63607664640
0
63607664640
63607664640

在这里插入图片描述
由上可以不管该文件在哪,返回该盘的容量大小,不存在的文件返回0.

(27)
public long getFreeSpace();
public long getUsableSpace();

  public long getFreeSpace() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
            sm.checkRead(path);
        }
        if (isInvalid()) {
            return 0L;
        }
        return fs.getSpace(this, FileSystem.SPACE_FREE);
    }
  public long getUsableSpace() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
            sm.checkRead(path);
        }
        if (isInvalid()) {
            return 0L;
        }
        return fs.getSpace(this, FileSystem.SPACE_USABLE);
    }

跟上面实现额方法一样,只是传入的常量不同而已.

public long getFreeSpace()
返回分区未分配的字节数named此抽象路径名。
返回的未分配字节数是一个提示,但不是保证,可以使用大多数或任何这些字节。 在此呼叫之后,未分配字节的数量很可能是准确的。 任何外部I / O操作(包括在该虚拟机之外的系统上进行的操作)都可能导致不准确。 此方法不保证对该文件系统的写入操作将成功。
结果
分区上的未分配字节数或0L(如果抽象路径名未命名分区)。 该值将小于或等于由getTotalSpace()返回的总文件系统大小。
异常
SecurityException - 如果已安装安全管理器,并且拒绝RuntimePermission (“getFileSystemAttributes”)或其SecurityManager.checkRead(String)方法拒绝对此抽象路径名命名的文件的读取访问权限

public long getUsableSpace()
返回上的分区提供给该虚拟机的字节数named此抽象路径名。 如果可能,此方法将检查写入权限和其他操作系统限制,因此通常会提供比getFreeSpace()实际写入多少新数据的更准确的估计。
返回的可用字节数是一个提示,但不是保证,可以使用大多数或任何这些字节。 在此呼叫之后,未分配字节的数量很可能是准确的。 任何外部I / O操作(包括在该虚拟机之外的系统上进行的操作)都可能导致不准确。 此方法不保证对该文件系统的写入操作将成功。
结果
分区上的可用字节数或0L,如果抽象路径名不命名分区。 在此信息不可用的系统上,此方法将等同于调用getFreeSpace() 。
异常
SecurityException - 如果安全管理器已安装,并且拒绝RuntimePermission (“getFileSystemAttributes”)或其SecurityManager.checkRead(String)方法拒绝对此抽象路径名命名的文件的读访问权限
@Test

    @Test
    public void getFreeSpace() {
        File file = new File("F:\\FileStudy\\test1.txt");//存在的文件
        File file1 = new File("F:\\FileStudy\\test1.t1xt");//不存在该文件
        File file2 = new File("F:\\FileStudy");//目录
        File file3 = new File("F:");//根目录

        System.out.println(file.getFreeSpace());
        System.out.println(file1.getFreeSpace());
        System.out.println(file2.getFreeSpace());
        System.out.println(file3.getFreeSpace());
    }

    @Test
    public void getUsableSpace() {
        File file = new File("F:\\FileStudy\\test1.txt");//存在的文件
        File file1 = new File("F:\\FileStudy\\test1.t1xt");//不存在该文件
        File file2 = new File("F:\\FileStudy");//目录
        File file3 = new File("F:");//根目录

        System.out.println(file.getUsableSpace());
        System.out.println(file1.getUsableSpace());
        System.out.println(file2.getUsableSpace());
        System.out.println(file3.getUsableSpace());
    }
输出结果都是:
57936908288
0
57936908288
57936908288
上面文档有解释

在这里插入图片描述
(28)
public static File createTempFile(String prefix, String suffix,File directory);
public static File createTempFile(String prefix, String suffix) throws IOException;

    public static File createTempFile(String prefix, String suffix,
                                      File directory)
        throws IOException
    {
        if (prefix.length() < 3)
            throw new IllegalArgumentException("Prefix string too short");
        if (suffix == null)
            suffix = ".tmp";

        File tmpdir = (directory != null) ? directory
                                          : TempDirectory.location();
        SecurityManager sm = System.getSecurityManager();
        File f;
        do {
            f = TempDirectory.generateFile(prefix, suffix, tmpdir);

            if (sm != null) {
                try {
                    sm.checkWrite(f.getPath());
                } catch (SecurityException se) {
                    // don't reveal temporary directory location
                    if (directory == null)
                        throw new SecurityException("Unable to create temporary file");
                    throw se;
                }
            }
        } while ((fs.getBooleanAttributes(f) & FileSystem.BA_EXISTS) != 0);

        if (!fs.createFileExclusively(f.getPath()))
            throw new IOException("Unable to create temporary file");

        return f;
    }
    
public static File createTempFile(String prefix, String suffix)
        throws IOException
    {
        return createTempFile(prefix, suffix, null);
    }
    
private static class TempDirectory {
        private TempDirectory() { }

        // temporary directory location
        private static final File tmpdir = new File(AccessController
            .doPrivileged(new GetPropertyAction("java.io.tmpdir")));
        static File location() {
            return tmpdir;
        }

        // file name generation
        private static final SecureRandom random = new SecureRandom();
        static File generateFile(String prefix, String suffix, File dir)
            throws IOException
        {
            long n = random.nextLong();
            if (n == Long.MIN_VALUE) {
                n = 0;      // corner case
            } else {
                n = Math.abs(n);
            }

            // Use only the file name from the supplied prefix
            prefix = (new File(prefix)).getName();

            String name = prefix + Long.toString(n) + suffix;
            File f = new File(dir, name);
            if (!name.equals(f.getName()) || f.isInvalid()) {
                if (System.getSecurityManager() != null)
                    throw new IOException("Unable to create temporary file");
                else
                    throw new IOException("Unable to create temporary file, " + f);
            }
            return f;
        }
    }

public static File createTempFile(String prefix,
String suffix,
File directory)
throws IOException
在指定的目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。 如果此方法成功返回,则可以保证:

在调用此方法之前,由返回的抽象路径名表示的文件不存在
该方法和其任何变体都不会在当前虚拟机的调用中再次返回相同的抽象路径名。
此方法仅提供临时文件设施的一部分。 要安排通过此方法创建的文件被自动删除,请使用deleteOnExit()方法。
prefix参数必须至少有三个字符长。 建议前缀为短的有意义的字符串,如"hjb"或"mail" 。 suffix参数可以是null ,在这种情况下将使用后缀".tmp" 。

要创建新文件,可以首先调整前缀和后缀以适应底层平台的限制。 如果前缀太长,那么它将被截断,但它的前三个字符将始终保留。 如果后缀太长,那么它也将被截断,但是如果以句点字符( ‘.’ )开头,那么它的周期和前三个字符将始终保留。 一旦进行了这些调整,将通过连接前缀,五个或更多内部生成的字符和后缀来生成新文件的名称。

如果directory参数是null那么将使用系统相关的默认临时文件目录。 默认临时文件目录由系统属性java.io.tmpdir 。 在UNIX系统上,此属性的默认值通常为"/tmp"或"/var/tmp" ; 在Microsoft Windows系统上,通常是"C:\WINNT\TEMP" 。 当Java虚拟机被调用时,可以向该系统属性赋予不同的值,但不能保证对此属性的编程更改对此方法使用的临时目录有任何影响。

参数
prefix - 用于生成文件名的前缀字符串; 长度必须至少为3个字符
suffix - 用于生成文件名的后缀字符串; 可能是null ,在这种情况下将使用后缀".tmp"
directory -其中文件是要创建的目录,或 null如果默认临时文件目录将被使用
结果
表示新创建的空文件的抽象路径名
异常
IllegalArgumentException - 如果 prefix参数包含少于三个字符
IOException - 如果无法创建文件
SecurityException - 如果安全管理器存在,并且其 SecurityManager.checkWrite(java.lang.String)方法不允许创建文件

该方法设计很巧妙,利用一个静态内部类完成一些基本操作,最后在外部调用完成操作.

createNewFile()与createTempFile()的区别:https://blog.csdn.net/Double2hao/article/details/50363532

(29)public Path toPath();

    public Path toPath() {
        Path result = filePath;
        if (result == null) {
            synchronized (this) {
                result = filePath;
                if (result == null) {
                    result = FileSystems.getDefault().getPath(path);
                    filePath = result;
                }
            }
        }
        return result;
    }
}

public Path toPath()
返回从该抽象路径构造的java.nio.file.Path对象。 Path的Path与default-filesystem有关 。
该方法的第一次调用的工作原理就像调用它相当于评估表达式:

FileSystems.getDefault().getPath(this.getPath());

此方法的Path调用返回相同的Path 。
如果此抽象路径Path空抽象路径名,则此方法返回可用于访问当前用户目录的Path。

结果
一个从这个抽象路径 Path Path
异常
InvalidPathException - 如果无法从抽象路径 Path对象(参见 FileSystem.getPath )

总结:未完待续

发布了17 篇原创文章 · 获赞 0 · 访问量 7221
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章