java中在上传文件或者下载文件的时候,或者获取配置文件的时候,经常需要获取工程中的文件的路径地址,这里介绍几种java中获取路径的方式
先说一个概念,classpath,就是在进行编译后,class文件,xml、properties等配置文件所在的目录。比如,如果是maven项目,classpath为“项目名/target/classes”,如果是普通项目,可能是”项目名/bin”,或者”项目名/build/classes”等等。
- 先看看我工程大概
1. getClass().getResource()
getResource(),接收一个字符串,如果字符串为"",则返回该class文件所在的目录,maven也就是/target/classes
目录加上包名
@Test
public void getPath() throws IOException {
//获取当前文件所在的路径
String localPath = this.getClass().getResource("").getPath();
System.out.println("localPath = " + localPath);
//localPath = /C:/work/idea-WorkSpace/my-demo/demo-file/target/classes/com/zgd/demo/file/path/
}
可见获取的是编译后的classes目录中的包名的文件夹的路径
但是这样获取的.前面有一个"/"斜杠的前缀,这样会导致一系列问题.所以我们使用的时候一般需要加上substring(1)
去掉前缀
比如这里贴一个java8中,通过Paths工具类,Files工具类,简单的获取到json信息的方法:
public static JSONObject readJson(String resourcesName){
Path f = Paths.get(JsonFileUtil.class.getResource("/").getPath().substring(1),resourcesName);
try {
List<String> strs = Files.readAllLines(f, Charset.forName("UTF-8"));
log.info("读取到行数:{}",strs.size());
String str = strs.stream().collect(Collectors.joining());
return JSON.parseObject(str);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
还是getClass().getResource,只不过字符串传"/"
@Test
public void getPath() throws IOException {
//获取项目根目录
String rootPath = this.getClass().getResource("/").getPath();
System.out.println("rootPath = " + rootPath);
//rootPath = /C:/work/idea-WorkSpace/my-demo/demo-file/target/classes/
}
可见得到的是/target/classes这个目录,也就是编译后的字节码,配置文件所在的根目录.
那么如果想获取resources中的4.jpg,因为编译后resources中的文件会拷贝到target/classes
中
,所以只需要传"/4.jpg".this.getClass().getResource("/4.jpg").getPath().subString(1);
这里需要注意一点,resources中,如果文件夹为空,不会将空文件夹拷贝到classes中
2.getClass().getClassLoader().getResource()
顾名思义,这个是获取到类加载器class loader所在路径. 先试试传空字符串""
@Test
public void getPath() throws IOException {
URL cl = this.getClass().getClassLoader().getResource("");
System.out.println("cl = " + cl);
//cl = file:/C:/work/idea-WorkSpace/my-demo/demo-file/target/classes/
String clp = cl.getPath();
System.out.println("clp = " + clp);
//clp = /C:/work/idea-WorkSpace/my-demo/demo-file/target/classes/
}
可见获取的是classpath的地址,而且得到的URL是自带前缀的,也就是"file:",我们并不需要,使用getPath方法会帮我们去掉这个前缀,当然,还是有"/"斜杠这个前缀
我们来试试获取classpath中的a.json:
@Test
public void getPath() throws IOException {
String cl2 = this.getClass().getClassLoader().getResource("a.json").getPath();
System.out.println("cl2 = " + cl2);
//cl2 = /C:/work/idea-WorkSpace/my-demo/demo-file/target/classes/a.json
}
也是可以的.
那么我们再来试试传一个斜杠"/":
@Test
public void getPath() throws IOException {
String cl3 = this.getClass().getClassLoader().getResource("/").getPath();
System.out.println("cl3 = " + cl3);
}
结果报空指针异常. 这是因为this.getClass().getClassLoader().getResource("/")
得到的是null
3. new File()
同样的,接收一个字符串
我们先试试什么都不传
@Test
public void getPath() throws IOException {
File file = new File("");
String f = file.getPath();
System.out.println("f = " + f);
//f =
}
什么都没有
但是它除了getPath,还有两个方法
@Test
public void getPath() throws IOException {
File abc = new File("a");
System.out.println("abc.getPath() = " + abc.getPath());
//abc.getPath() = a
//获取绝对路径
String absolutePath = abc.getAbsolutePath();
System.out.println("absolutePath = " + absolutePath);
//absolutePath = C:\work\idea-WorkSpace\my-demo\demo-file\a
//获取规范化路径
String canonicalPath = abc.getCanonicalPath();
System.out.println("canonicalPath = " + canonicalPath);
//canonicalPath = C:\work\idea-WorkSpace\my-demo\demo-file\a
//获取相对路径
String path = abc.getPath();
System.out.println("path = " + path);
//path = abc
}
可见它获取的是这个工程的路径,而不是classpath的路径.而且获取的路径,前面没有斜杠,不需要subString
这样的话我们可以获取这个工程下的文件,比如不属于src目录,也不会被编译进classpath的pom.xml
,和README.md
文件, 甚至我们也可以自己加上target/classes
来获取resources中的文件
@Test
public void getPath() throws IOException {
File abcd = new File("README.md");
System.out.println("abcd.exists() = " + abcd.exists());
//abcd.exists() = true
File abcde = new File("target/classes/4.jpg");
System.out.println("abcde.exists() = " + abcde.exists());
}
最后看看传空字符串和传斜杠得到的绝对地址是什么:
@Test
public void getPath() throws IOException {
String absolutePath1 = new File("").getAbsolutePath();
System.out.println("absolutePath1 = " + absolutePath1);
//absolutePath1 = C:\work\idea-WorkSpace\my-demo\demo-file
String absolutePath2 = new File("/").getAbsolutePath();
System.out.println("absolutePath2 = " + absolutePath2);
//absolutePath2 = C:\
}
可见传空字符串,绝对地址是该工程的目录地址
传斜杠,得到的是这个盘符的根目录
4.System.getProperty()
我们也可以直接用System的属性得到路径
@Test
public void getPath() throws IOException {
// 获取工程路径
String sp1 = System.getProperty("user.dir");
System.out.println("sp1 = " + sp1);
//sp1 = C:\work\idea-WorkSpace\my-demo\demo-file
}
得到的仍然是该工程项目的目录