栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java关于File类源码的详细分析 附代码(全)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java关于File类源码的详细分析 附代码(全)

目录
  • 前言
  • 1. 属性
  • 2. 构造函数
  • 3. 方法
    • 3.1 常用方法
    • 3.2 磁盘与临时文件
    • 3.3 其他

前言

磁驱动分割符中,在unix中使用/表示,在window中使用\

查看其源码,实现Serializable, Comparable的接口

public class File
    implements Serializable, Comparable
{

对于Serializable的具体功能可看我这篇文章:java之序列化与反序列化的详细解析(全)
对于Comparable的接口可看我这篇文章稍微提及的知识点:javaSE从入门到精通的二十万字总结(二)

1. 属性

其具体属性定义如下:

// 文件系统对象
// 后面很多方法也用到了文件系统类的方法,比如系统创建文件的时间等,这里简称fs,后面多处都用到了
private static final FileSystem fs = DefaultFileSystem.getFileSystem();

// 路径名
private final String path;

// 枚举类型
// file类对象的地址是否合法通过枚举类判定
private static enum PathStatus { INVALID, CHECKED };

// 文件路径是否有效
private transient PathStatus status = null;
// 检查路径是否有效 但只涉及nul字符,true绝对无效,false不一定有效
final boolean isInvalid() {
    if (status == null) {
        status = (this.path.indexOf('u0000') < 0) ? PathStatus.CHECKED
                                                   : PathStatus.INVALID;
    }
    return status == PathStatus.INVALID;
}

// 路径名前缀长度
private final transient int prefixLength;
int getPrefixLength() {
    return prefixLength;
}

// 依赖系统分隔符
public static final char separatorChar = fs.getSeparator();
// 将其转换为字符串表示
public static final String separator = "" + separatorChar;
2. 构造函数
函数描述
public File(String pathname)创建路径名实例
public File(String parent, String child)父+子路径 创建实例
public File(URI uri)根据URI 路径创建一个新的 File 实例

源码如下:(部分已加注释, 可配合下方的具体例子理解)

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

// 根据URI 路径创建一个新的 File 实例
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);
}

具体实现代码如下:

public class file {
    public static void main(String [] args){
		// 这样子会出错
		// File file = new File();
		
        File file = new File("");
        System.out.println(file); // 输出为空

        File file1 = new File("manongyanjiuseng");
        System.out.println(file1); // 输出manongyanjiuseng

		
		
		// manong为父路径名字 ,yanjiuseng 为子路径名字
		// 父路径不为空的时候,既通过父+子路径的拼接
        File file2 = new File("manong","yanjiuseng");
        System.out.println(file2); // 输出manongyanjiuseng
		
		// 如果父路径为空的时候,既通过输出子路径创建实例即可
		String parent = null;
        File file3 = new File(parent, "manongyanjisueng");
        System.out.println(file3);// 输出manongyanjiuseng
		
		// 如果子路径为空,后面跟着null,空指针就会抛出异常
        String child = null;
        File file4 = new File("manongyanjisueng", child);
        System.out.println(file4);// 抛出异常
        // 异常 Exception in thread "main" java.lang.NullPointerException
    }
}

结果输出如下:

最后一种构造函数比较特殊 单独拎出来
根据URI 路径创建一个新的 File 实例

public class file {
    public static void main(String [] args){
        File file5;
        try {
            file5 = new File(new URI("file:///C:/Users/13399/Desktop"));
            System.out.println(file5.getName());// 输出 Desktop
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
}       

截图如下:

3. 方法
函数描述
getName()获取文件名
getParent()获取上级目录
getParentFile()默认 以上级目录为父路径创建实例
getPath()输出文件实际路径
isAbsolute()是否以window系统的磁盘文件
getAbsolutePath()获取文件的绝对路径
exists()实例的file类对象是否存在
isFile()是否为文件
isDirectory()是否为目录
createNewFile()创建文件
mkdir()创建(前提是父目录存在)单目录true,文件false
mkdirs()可创建多级目录,即使单目录也可,区分一点就是,父目录不存在也可创建
delete()删除文件或者文件夹(文件夹必须为空才可删除)

使用方法,按照惯例,先看一波源码(已加注释)

3.1 常用方法

常用方法源码具体如下(已加上注释):

// 返回文件或者目录的名称
public String getName() {
	// public static final char separatorChar = fs.getSeparator();
	// 此处的separatorChar 为系统分割符号,也就是获取最后一个分割符的名字
    int index = path.lastIndexOf(separatorChar);
    // 判断下,防止异常
    if (index < prefixLength) return path.substring(prefixLength);
    return path.substring(index + 1);
}

// 获取上级目录
// 代码注释跟上面一样,唯一的区别在于获取上级目录,所以通过substring截取即可
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);
}

// 获取上级目录之后在实例对象
public File getParentFile() {
	// 通过this指针获取上级目录
    String p = this.getParent();
    if (p == null) return null;
    if (getClass() != File.class) {
        p = fs.normalize(p);
    }
    return new File(p, this.prefixLength);
}

// 返回路径,抽象路径的字符串形式
public String getPath() {
   return path;
}

// 测试是否是绝对路径

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

// 获取绝对路径
public String getAbsolutePath() {
   return fs.resolve(this);
}

// 获取绝对路径,相当于new File(this.getAbsolutePath)
// 注意与上面的区别,一个是file类一个是String类
public File getAbsoluteFile() {
    String absPath = getAbsolutePath();
    if (getClass() != File.class) {
    	// 给定的路径字符串转换为正常形式,如果字符串已经是正常形式 无需转换 
        absPath = fs.normalize(absPath);
    }
    return new File(absPath, fs.prefixLength(absPath));
}

对于上面的normalize格式化函数
有如下三个源代码函数

public String normalize(String path)
private String normalize(String path, int len, int off)
private int normalizePrefix(String path, int len, StringBuilder sb)

内部函数代码用到的变量

// 区分系统盘符
slash = props.getProperty("file.separator").charAt(0);
altSlash = (this.slash == '\') ? '/' : '\';

核心代码如下 浅显易懂就post图出来

是否存在、被隐藏、读取修改等源码
源代码如下:

// FileSystem类 属性

@Native public static final int BA_EXISTS    = 0x01;
@Native public static final int BA_REGULAR   = 0x02;
@Native public static final int BA_DIRECTORY = 0x04;
@Native public static final int BA_HIDDEN    = 0x08;

// 判断文件或者路径是否存在
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);
}


// 判断此抽象路径名表示的是否为目录
public boolean isDirectory() {
  // 代码同exists()函数
    return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
            != 0);
}

// 判断此抽象路径名表示的是否为文件
public boolean isFile() {
    // 代码同exists()函数
    return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
}

// 路径名命名的文件是否为隐藏文件,取决于操作系统
public boolean isHidden() {
     // 代码同exists()函数
     return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
 }

文件是否被读取修改等权限源码:
关于下面这个注解可看我之前的文章:Springboot中@SuppressWarnings注解详细解析
主要为了屏蔽一些错误警告,但不是代码错误警告

// FileSystem类 属性
@Native public static final int ACCESS_READ    = 0x04;
@Native public static final int ACCESS_WRITE   = 0x02;
@Native public static final int ACCESS_EXECUTE = 0x01;

// 文件或者目录可否被读取
public boolean canRead() {
    @SuppressWarnings("removal")
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkRead(path);
    }
    if (isInvalid()) {
        return false;
    }
    return fs.checkAccess(this, FileSystem.ACCESS_READ);
}

// 文件或者目录可否被修改
public boolean canWrite() {
    @SuppressWarnings("removal")
	// 代码同上
	if (security != null) {
        security.checkWrite(path);
    }
    // ...
    return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
}

// 文件或者目录可否被执行
public boolean canExecute() {
    @SuppressWarnings("removal")
   // 代码同上
	if (security != null) {
        security.checkExec(path);
    }
    // ...
    return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
}

以及最后的修改时间lastModified,长度length

public long lastModified() {
    @SuppressWarnings("removal")
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkRead(path);
    }
    if (isInvalid()) {
        return 0L;
    }
    
    // 获取的系统文件时间 
    // 等同于 调用的最终函数 public native long getLastModifiedTime(File f);
    return fs.getLastModifiedTime(this);
}

// 路径名表示的文件的长度。如果此路径名表示目录,则返回值未指定
public long length() {
    @SuppressWarnings("removal")
	// 省略代码,同lastModified函数
	
	// 获取系统文件长度
	// 等同于 调用的最终函数 public native long getLength(File f);
    return fs.getLength(this);
}

具体例子如下:

import java.io.IOException;
import java.io.File;
public class file {
    public static void main(String [] args){
        File file = new File("C:/Users/13399/Desktop");
        // 输出文件名
        System.out.println(file.getName()); // Desktop

        // 输出上级目录
        System.out.println(file.getParent()); // C:Users13399

        File file1 = new File("C:/Users/13399","Desktop");
        // 未指定父路径,默认以上级目录为父路径创建实例
        System.out.println(file.getParentFile()); // C:Users13399
        // 指定父路径,则以父路径创建实例
        System.out.println(file1.getParentFile()); // C:Users13399

        // 输出文件实际路径
        System.out.println(file.getPath()); // C:Users13399Desktop

        // 是否以window系统的磁盘文件
        System.out.println(file.isAbsolute()); // true

        // 获取文件的绝对路径
        System.out.println(file.getAbsolutePath()); // C:Users13399Desktop

        // 实例的file类对象是否存在
        System.out.println(file.exists()); // true

        //  是否为文件
        System.out.println(file.isFile()); // false

        // 是否为目录
        System.out.println(file.isDirectory()); // true

        // 创建新文件,只有文件不存在的时候才可以创建
        try {
            System.out.println(file.createNewFile()); // false 已存在无需创建
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 删除,为空的时候才可以删除
        System.out.println(file.delete()); // false
    }
}

创建、删除操作源码

// 创建文件
public boolean createNewFile() throws IOException {
    SecurityManager security = System.getSecurityManager();
    if (security != null) security.checkWrite(path);
    if (isInvalid()) {
        throw new IOException("Invalid file path");
    }
	// 获取系统文件长度
	// 等同于 调用的最终函数 public native boolean createFileExclusively(String path) throws IOException;
    return fs.createFileExclusively(path);
}


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


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

// 创建以此抽象路径名命名的目录
public boolean mkdir() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkWrite(path);
    }
    if (isInvalid()) {
        return false;
    }
    // 此为Filesystem类下的抽象方法
    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;
    }
	// 返回此抽象路径名的父目录的抽象路径名,如果此路径名未命名父目录,则返回null
    File parent = canonFile.getParentFile();
    return (parent != null && (parent.mkdirs() || parent.exists()) &&
            canonFile.mkdir());
}

对于创建文件、单目录、多目录、删除操作都是由File类新建对象来决定的

File file = new File("???")

mkdir的例子具体如下:

// 原路径为C:/Users/13399/Desktop
File file3 = new File("C:/Users/13399/Desktop/11"); 
System.out.println(file3.mkdir()); // 创建11目录,成功创建为true

// 原路径为C:/Users/13399/Desktop
File file4 = new File("C:/Users/13399/Desktop/11.txt");
System.out.println(file4.mkdir()); // 创建的11.txt为文件,则为false,不成功

// 无法创建不存在的多级目录 或者 不存在的父目录下创建 

mkdirs的例子具体如下:

// 原路径为C:/Users/13399/Desktop
File file3 = new File("C:/Users/13399/Desktop/13");
System.out.println(file3.mkdirs()); // 创建13目录,成功创建为true

// 原路径为C:/Users/13399/Desktop
File file4 = new File("C:/Users/13399/Desktop/13.txt");
System.out.println(file4.mkdirs()); // 创建的13.txt为文件,也可创建,为true

// 创建不存在的多级目录 也可创建成功

遍历列表源码

// 返回一个数组表示文件
public File[] listFiles() {
    String[] ss = normalizedList();
    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;
}

// 这个与上面的不同,多了一个filter 主要是过滤
public File[] listFiles(FilenameFilter filter) {
    String ss[] = normalizedList();
    if (ss == null) return null;
    ArrayList files = new ArrayList<>();
    for (String s : ss)
    	// 区别在于这个核心代码中,filter为null 或者对应过滤相应文件,this表示当前路径
    	// accept 主要是 测试是否应将指定的文件包含在文件列表中
    	// 核心函数 boolean accept(File dir, String name); 重构这个函数即可
        if ((filter == null) || filter.accept(this, s))
            files.add(new File(s, this));
    return files.toArray(new File[files.size()]);
}

// 注意与上方函数模块的不同
public File[] listFiles(FileFilter filter) {
    String ss[] = normalizedList();
    if (ss == null) return null;
    ArrayList files = new ArrayList<>();
    for (String s : ss) {
        File f = new File(s, this);
        //测试指定的抽象路径名是否应包含在路径名列表中
        // 核心函数 boolean accept(File pathname);重构这个函数即可
        if ((filter == null) || filter.accept(f))
            files.add(f);
    }
    return files.toArray(new File[files.size()]);
}

具体示例代码如下:
为了对比不同,此处引入list返回的是String类型

File file = new File("C:/Users/13399/Desktop/13");

System.out.println(Arrays.toString(file.list())); // 输出目录中各个文件名
System.out.println(Arrays.toString(file.listFiles())); // 输出目录中各个文件的绝对路径

// 查看源码可得知 重构函数即可
// 区分list 返回值 String[] list = file.list(
File[] list = file.listFile((File dir, String name) ->name.endsWith(".xml") // 筛选过滤出.xml文件,之后输出这个文件的绝对路径
);
System.out.println(Arrays.toString(list));

// 区别在于重构函数不同
File[] list1 = file.listFiles((File dir, String name) -> name.endsWith(".xml")); // 筛选过滤出.xml文件,之后输出这个文件的绝对路径
System.out.println(Arrays.toString(list1));
3.2 磁盘与临时文件

磁盘文件源码

@Native public static final int SPACE_TOTAL  = 0;
@Native public static final int SPACE_FREE   = 1;
@Native public static final int SPACE_USABLE = 2;

// 返回由此抽象路径名命名的分区的大小
// 分区的大小(以字节为单位),如果此抽象路径名未命名分区,则为0L
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);
}


// 此抽象路径名命名的分区中未分配的字节数 注意区别,就一行代码不同
public long getFreeSpace() {
    // 代码同getTotalSpace()
    return fs.getSpace(this, FileSystem.SPACE_FREE);
}

// 返回此抽象路径名命名的分区上此虚拟机可用的字节数 注意区别,就一行代码不同
public long getUsableSpace() {
    // 代码同getTotalSpace()
    return fs.getSpace(this, FileSystem.SPACE_USABLE);
}

临时文件源码

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
{
	// 前缀长度小于3 会抛出异常,必须至少是3的长度以上
    if (prefix.length() < 3) {
        throw new IllegalArgumentException("Prefix string "" + prefix +
            "" too short: length must be at least 3");
    }
    // 如果后缀为null,则默认给予赋值
    if (suffix == null)
        suffix = ".tmp";
	
	// 判断目录是否为空,为空则创建一个临时的文件目录
	// 具体文件目录有系统决定,unix默认值为 /tmp 或 /var/tmp,windiow下为C:WINNTTEMP
    File tmpdir = (directory != null) ? directory
                                      : TempDirectory.location();

    @SuppressWarnings("removal")
    // 次函数与安全管理器有关
    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.hasBooleanAttributes(f, FileSystem.BA_EXISTS));

    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);
}
3.3 其他

基本的方法函数源码:

// 比较两个抽象路径名,通过字典顺序的方法
// 具体比较还是根据操作系统,毕竟unix字母大小写很重要
public int compareTo(File pathname) {
   return fs.compare(this, pathname);
}

// 测试路径名与给定的对象是否相等,是否相等取决于操作系统
public boolean equals(Object obj) {
	// instanceof 判断是否是这个实例对象
    if (obj instanceof File file) {
        return compareTo(file) == 0;
    }
    return false;
}

// 哈希码
public int hashCode() {
   return fs.hashCode(this);
}

// 返回路径名,只不过通过getPath返回字符串
public String toString() {
   return getPath();
}

以上代码都是基本的代码,没什么特殊之处

源码部分中还跟其他的类集成源码:

// 保存文件名以及分隔符,不同系统如果不同的时候可以重建,并且替换
@java.io.Serial
private synchronized void writeObject(java.io.ObjectOutputStream s)
    throws IOException
{
    s.defaultWriteObject();
    s.writeChar(separatorChar); // Add the separator character
}

// 读取文件名以及原始分割符,如果与系统分割符不同,则用旧的替换当前的
@java.io.Serial
private synchronized void readObject(java.io.ObjectInputStream s)
     throws IOException, ClassNotFoundException
{
    ObjectInputStream.GetField fields = s.readFields();
    String pathField = (String)fields.get("path", null);
    char sep = s.readChar(); // read the previous separator char
    if (sep != separatorChar)
        pathField = pathField.replace(sep, separatorChar);
    String path = fs.normalize(pathField);
    UNSAFE.putReference(this, PATH_OFFSET, path);
    UNSAFE.putIntVolatile(this, PREFIX_LENGTH_OFFSET, fs.prefixLength(path));
}

// 集成java.nio.file
private transient volatile Path filePath;

// 返回相同的path,如果为空路径名,则可用于访问当前用户目录的 Path
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;
}

对于上面toPath()这个方法中用到的synchronized关键字
可看我这篇文章:java并发之synchronized详细分析(全)
抽象出来,类似设计模式中的单例:JAVA设计模式之单例模式详细分析(全)

    public String getAbsolutePath(String filename){
        File file = new File(filename);
        return file.getAbsolutePath().trim().replaceAll("\\", "/");
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1031093.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号