java几种获取工程项目文件路径的方式

java中在上传文件或者下载文件的时候,或者获取配置文件的时候,经常需要获取工程中的文件的路径地址,这里介绍几种java中获取路径的方式

先说一个概念,classpath,就是在进行编译后,class文件,xml、properties等配置文件所在的目录。比如,如果是maven项目,classpath为“项目名/target/classes”,如果是普通项目,可能是”项目名/bin”,或者”项目名/build/classes”等等。

  • 先看看我工程大概
    java几种获取工程项目文件路径的方式

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
}

得到的仍然是该工程项目的目录

上一篇:python-使用Google App Engine和Bottle提供静态HTML


下一篇:zookeeper的Java API