Java IO体系之File

IO体系图

这里写图片描述

简单介绍

Java.io.File类主要是完成了文件夹管理的命名、查询文件属性和处理目录等操作,它不进行文件夹内容的读取操作。

源码分析

继承关系

实现了java.io.Serializable接口,java.lang.Comparable接口【内比较器】

public class File
    implements Serializable, Comparable<File>

成员变量

/**
 * 表示平台本地文件系统的文件系统对象。
 */
private static final FileSystem fs = DefaultFileSystem.getFileSystem();

/**
* 文件抽象路径
*/
private final String path;

/**
* 表示地址是否合法的enum类
*/
private static enum PathStatus { INVALID, CHECKED };

/**
* 标记文件路径是否无效
*/
private transient PathStatus status = null;


/**
* 抽象路径名的前缀的长度,如果没有前缀,则为0。使用transient修饰符表示持久化时忽略该属性。
*/
private final transient int prefixLength;

/**
 * 名称分隔符,在UNIX系统中此字段值是’/’,在WINDOWS系统中此字符的值是’\\’。
 */
public static final char separatorChar = fs.getSeparator();

public static final String separator = "" + separatorChar;

/**
 * 路径分割符,在UNIX系统中此字段值是':',在WINDOWS系统中此字符的值是';'。
 */
public static final char pathSeparatorChar = fs.getPathSeparator();

public static final String pathSeparator = "" + pathSeparatorChar;

构造函数

private File(String pathname, int prefixLength) {
    this.path = pathname;
    this.prefixLength = prefixLength;
}

private File(String child, File parent) {
    assert parent.path != null;
    assert (!parent.path.equals(""));
    this.path = fs.resolve(parent.path, child);
    this.prefixLength = parent.prefixLength;
}

public File(String pathname) {
    if (pathname == null) {
        throw new NullPointerException();
    }
    this.path = fs.normalize(pathname);
    this.prefixLength = fs.prefixLength(this.path);
}

public File(String parent, String child) {
    if (child == null) {
        throw new NullPointerException();
    }
    if (parent != null) {
        if (parent.equals("")) {
            this.path = fs.resolve(fs.getDefaultParent(),
                                   fs.normalize(child));
        } else {
            this.path = fs.resolve(fs.normalize(parent),
                                   fs.normalize(child));
        }
    } else {
        this.path = fs.normalize(child);
    }
    this.prefixLength = fs.prefixLength(this.path);
}

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

public File(URI uri) {

    // Check our many preconditions
    if (!uri.isAbsolute())
        throw new IllegalArgumentException("URI is not absolute");
    if (uri.isOpaque())
        throw new IllegalArgumentException("URI is not hierarchical");
    String scheme = uri.getScheme();
    if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
        throw new IllegalArgumentException("URI scheme is not \"file\"");
    if (uri.getAuthority() != null)
        throw new IllegalArgumentException("URI has an authority component");
    if (uri.getFragment() != null)
        throw new IllegalArgumentException("URI has a fragment component");
    if (uri.getQuery() != null)
        throw new IllegalArgumentException("URI has a query component");
    String p = uri.getPath();
    if (p.equals(""))
        throw new IllegalArgumentException("URI path component is empty");

    // Okay, now initialize
    p = fs.fromURIPath(p);
    if (File.separatorChar != '/')
        p = p.replace('/', File.separatorChar);
    this.path = fs.normalize(p);
    this.prefixLength = fs.prefixLength(this.path);
}

常用方法

/**
 * Check if the file has an invalid path. 
 */
final boolean isInvalid() {
    if (status == null) {
        status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
                                                   : PathStatus.INVALID;
    }
    return status == PathStatus.INVALID;
}

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

/**  
* 返回文件名称或者对象对应的最后一个路径字符串。
*/
public String getName() {
   int index = path.lastIndexOf(separatorChar);
   if (index < prefixLength) return path.substring(prefixLength);
   return path.substring(index + 1);
}

/**
 * 返回当前File对象的上级路径名称
 */
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对象
*/
public File getParentFile() {
   String p = this.getParent();
   if (p == null) return null;
   return new File(p, this.prefixLength);
}


/**
 * @return  The string form of this abstract pathname
 */
public String getPath() {
    return path;
}

/**
* 判定当前File对象是否是绝对路径。
*/
public boolean isAbsolute() {
   return fs.isAbsolute(this);
}


/**
* Returns the absolute pathname string of this abstract pathname.
*/
public String getAbsolutePath() {
  return fs.resolve(this);
}

/**
* Returns the absolute form of this abstract pathname.  Equivalent to
* <code>new&nbsp;File(this.{@link #getAbsolutePath})</code>.
*/
public File getAbsoluteFile() {
  String absPath = getAbsolutePath();
  return new File(absPath, fs.prefixLength(absPath));
}



/**
 * Returns the canonical pathname string of this abstract pathname.
 */
public String getCanonicalPath() throws IOException {
    if (isInvalid()) {
        throw new IOException("Invalid file path");
    }
    return fs.canonicalize(fs.resolve(this));
}


/**
 * Returns the canonical form of this abstract pathname.  Equivalent to
 * <code>new&nbsp;File(this.{@link #getCanonicalPath})</code>.
 */
public File getCanonicalFile() throws IOException {
    String canonPath = getCanonicalPath();
    return new File(canonPath, fs.prefixLength(canonPath));
}

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



/**
* Constructs a <tt>file:</tt> URI that represents this abstract pathname.
*/
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
  }
}


/**
* Tests whether the application can read the file denoted by this
* abstract pathname. 
*/
public boolean canRead() {
   SecurityManager security = System.getSecurityManager();
   if (security != null) {
       security.checkRead(path);
   }
   if (isInvalid()) {
       return false;
   }
   return fs.checkAccess(this, FileSystem.ACCESS_READ);
}


/**
* Tests whether the application can modify the file denoted by this
* abstract pathname. 
*/
public boolean canWrite() {
   SecurityManager security = System.getSecurityManager();
   if (security != null) {
       security.checkWrite(path);
   }
   if (isInvalid()) {
       return false;
   }
   return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
}

/**
* 判断抽象路径名称给定的文件或者路径是否存在
*/
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);
}

/**
* 判断给定File对象是否是一个目录对象。
*/
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);
}

/**
* 判断File对象给定的路径名称是否是一个规范的文件
*/
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);
}

/**
* 判断抽象路径名指定的文件是否是一个隐藏的文件
*/
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);
}

/**
* Returns the time that the file denoted by this abstract pathname was
* last modified.
*/
public long lastModified() {
   SecurityManager security = System.getSecurityManager();
   if (security != null) {
       security.checkRead(path);
   }
   if (isInvalid()) {
       return 0L;
   }
   return fs.getLastModifiedTime(this);
}

/**
* 返回给定的抽象路径名称的文件长度。
*/
public long length() {
   SecurityManager security = System.getSecurityManager();
   if (security != null) {
       security.checkRead(path);
   }
   if (isInvalid()) {
       return 0L;
   }
   return fs.getLength(this);
}


/**
* 自动的创建一个新的空的文件,以给定的抽象路径名称为文件名
*/
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);
}


/**
 * Deletes the file or directory denoted by this abstract pathname.  If
 * this pathname denotes a directory, then the directory must be empty in
 * order to be deleted.
 */
public boolean delete() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkDelete(path);
    }
    if (isInvalid()) {
        return false;
    }
    return fs.delete(this);
}



/**
* 返回此抽象路径名指定的文件或者目录的集合
*/
public String[] list() {
   SecurityManager security = System.getSecurityManager();
   if (security != null) {
       security.checkRead(path);
   }
   if (isInvalid()) {
       return null;
   }
   return fs.list(this);
}

/**
 * Returns an array of strings naming the files and directories in the
 * directory denoted by this abstract pathname that satisfy the specified
 * filter.  
 */
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()]);
}


/**
 * 返回此抽象路径名指定的文件或者目录下的所有文件的集合
 */
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;
}

/**
* Returns an array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname that
* satisfy the specified filter.  
*/
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()]);
}

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

/**
* Creates the directory named by this abstract pathname, including any
* necessary but nonexistent parent directories.  Note that if this
* operation fails it may have succeeded in creating some of the necessary
* parent directories.
*/
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());
}

参考文档:

  1. https://blog.csdn.net/yaomingyang/article/details/79360277
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值