运维.售后
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
博客
Blog
ToB门户
了解全球最新的ToB事件
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
软件与程序人生
›
后端开发
›
Java
›
从new File("")到jdk源码
从new File("")到jdk源码
飞不高
金牌会员
|
2022-9-16 17:19:55
|
显示全部楼层
|
阅读模式
楼主
主题
884
|
帖子
884
|
积分
2652
1. 概述
今天在项目中看到下面两行代码,看注释说是获取当前工作路径,之前也没有用过这种用法,比较好奇还能这样用,所以研究了一下源码。
//获取当前工作路径
File file = new File("");
String currentWorkDirectory = file.getAbsolutePath();
复制代码
2. new File("")解析
首先,new File()是创建一个虚拟的文件(File)对象,通过这个对象可以调用很多方法来获取文件和目录的相关信息。以下列出一些常用方法:
2.1 File的常用方法
方法签名作用boolean delete()删除文件或目录void deleteOnExit()在jvm退出时删除文件或目录boolean createNewFile()当以这个文件名命名的文件不存在时,创建一个新的空文件boolean exists()判断文件或目录是否存在String getAbsolutePath()获取File对象的绝对路径String getName()获取文件或目录名称File getParentFile()获取父File对象String getPath()获取File对象创建时传入的pathname参数boolean isDirectory()判断是否是目录File[] listFiles()列出当前目录下的所有文件boolean mkdir()创建单个目录boolean mkdirs()创建多级目录
2.2 new File("")做了什么
我们先来看看源码是怎么描述的:
其中注释的意思是:将指定的文件路径转换为一个绝对路径,然后创建一个新的File实例。如果给定的文件路径参数为空值,则返回空的绝对路径名。
官方的注释比较难理解,通俗的将就是,当我传入一个相对路径就会转换为绝对路径,当我传入一个""参数时,就只有一个绝对路径。那么这个绝对路径代表什么含义呢?
2.3 深入源码看File绝对路径(abstract pathname)的含义
2.3.1 File.getAbsolutePath()方法
其实我们可以看到new File(String pathname)这个构造方法只设置了相对路径和解析相对路径的长度。并没有有关绝对路径的操作。那么究竟是在哪里设置的绝对路径呢?这个就涉及到getAbsolutePath()方法了。
下面我们看一下getAbsolutePath()方法做了什么:
从注释可以看出,如果在new File()的时候传入的pathname已经是绝对路径的话,那么这个方法的返回就和getPath()一样,如果传入的是空字符串的话,那么就返回当前目录的路径,通过系统属性user.dir获取。
2.3.2 WinNTFileSystem.resolve()方法
那么我们继续往下看:
点进去resolve()方法可以看到返回值实际是从getUserPath()这个方法获取的。
2.3.3 WinNTFileSystem.getUserPath()方法
getUserPath()方法调用了System.getProperty("user.dir")方法来获取user.dir这个key的配置。再往里面看user.dir的值其实是从props这个Properties对象中获取的。
2.3.4 System.setProperties(props)方法
那props又是从哪里拿到这个值的呢?我们接着往下看:
在System类里面对着props这个属性用ctrl+鼠标左键查找props在哪几个地方使用了。可以看到有一个setProperties(Properties props)方法。再对着setProperties这个方法使用ctrl+鼠标左键查找。
2.3.5 Process.main()方法
在com.sun.org.apache.xalan.internal.xslt.Process的main方法里面我们可以看到,执行了System.setProperties(props),而System.setProperties(props)调用了本地方法private static native Properties initProperties(Properties props)对props进行初始化。
2.3.6 System.initProperties(Properties props)本地方法
到这里的话,其实java源代码已经结束了,总结来说就是jvm在启动的时候调用了System类的private static native Properties initProperties(Properties props)本地方法对props属性进行初始化,设置了user.dir的值。
这时可能还有些好奇宝宝不甘心,为什么调用了这个本地方法就可以获取user.dir的值,那么我们就来研究一下openjdk的c语言源码吧。
2.4 深入openjdk源码
我们从github上搜索到openjdk的源码仓库,随便找一个java8的tag来研究initProperties()这个本地方法到底做了什么。
github的openjdk代码仓库
首先我们找到jdk/src/share/native/java/lang目录下面的System.c文件。在里面搜索一下initProperties,可以看到有一个Java_java_lang_System_initProperties方法。
接着我们在这个方法里面搜索user_dir,可以看到值是从一个sprops指针中获取的,而sprops从上一张图可以看出是从GetJavaProperties(env)这个方法获取的值。
那我们ctrl+shift+F全局搜索一下GetJavaProperties这个方法。可以看到jdk/src/windows/native/java/lang/java_props_md.c文件中有这个方法,从文件路径可以看出这个文件是windows系统下执行的。
接着在这个方法里面搜索user_dir,可以看到user_dir实际是从GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR), buf)方法里面获取值的。GetCurrentDirectoryW这个方法就是windows的系统函数,用来获取当前工作目录。
到这里jdk源码解析就结束了,可以看到在windows系统下是调用了它的系统函数获取当前工作目录。
备注:_wcsdup(buf)方法是c语言的库函数,作用是分配一块新的空间,然后从buf数组里面获取值赋值给新创建的空间。
3. 总结
绝对路径是什么:当前工作目录,就是当前项目的根路径
使用new File("")创建File对象时,绝对路径其实是getAbsolutePath()方法获取的,new File("")只是设置了path=""
System.props这个属性其实包含了很多值,如:java.version、user.home等等,可以看源码中的注释
通过System.getProperty(key)可以获取系统的一些配置信息
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
飞不高
金牌会员
这个人很懒什么都没写!
楼主热帖
WPF开发经验-实现自带触控键盘的TextBo ...
Java集合的lastlastIndexOfSubList()方 ...
如何在 K8S 集群范围使用 imagePullSec ...
Python批量采集百度资讯文章,如何自定 ...
【关系型数据库】事务特性及事务隔离级 ...
微信小程序集合3(百度小说+电商+仿哗 ...
自从用了 EasyExcel,导入导出 Excel ...
mysql总结
MapReduce开发
AnimateDiff论文解读-基于Stable Diffu ...
标签云
存储
服务器
快速回复
返回顶部
返回列表