MyException - 我的异常网
当前位置:我的异常网» 编程 » Java中的路径有关问题

Java中的路径有关问题

www.MyException.Cn  网友分享于:2015-08-26  浏览:10次
Java中的路径问题

“.”知识代表当前工作目录的意思,它是一个相对路径的写法,一般也就是jvm调用路径,可以通过
System.getProperty("user.dir")得到。

“.”当前的工作目录,即user.dir,相当于“.\\”;

“..”代表user.dir上层目录,与“..\\”等价
“/”linux下表示根目录,windows下表示user.dir所在盘符的根目录,同样等价于“\\”

  Java路径分类


  Java中使用的路径,分为两种:绝对路径和相对路径。具体而言,又分为四种:

  一、URI形式的绝对资源路径


  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

  URL是URI的特例。URL的前缀/协议,必须是Java认识的。URL可以打开资源,而URI则不行。

  URL和URI对象可以互相转换,使用各自的toURI(),toURL()方法即可!

  二、本地系统的绝对路径


  D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

  Java.io包中的类,需要使用这种形式的参数。

  但是,它们一般也提供了URI类型的参数,而URI类型的参数,接受的是URI样式的String。因此,通过URI转换,还是可以把URI样式的绝对路径用在java.io包中的类中。

  三、相对于classpath的相对路径


  如:相对于

  file:/D:/java/eclipse32/workspace/jbpmtest3/bin/这个路径的相对路径。其中,bin是本项目的classpath。所有的Java源文件编译后的.class文件复制到这个目录中。

  四、相对于当前用户目录的相对路径


  就是相对于System.getProperty("user.dir")返回的路径。

对于一般项目,这是项目的根路径。对于JavaEE服务器,这可能是服务器的某个路径。这个并没有统一的规范!
上述相对路径中,java项目中的文件是相对于项目的根目录
web项目中的文件路径视不同的web服务器不同而不同(tomcat是相对于 tomcat安装目录\bin)

  所以,绝对不要使用“相对于当前用户目录的相对路径”。然而:

  默认情况下,java.io 包中的类总是根据当前用户目录来分析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。

  这就是说,在使用java.io包中的类时,最好不要使用相对路径。否则,虽然在J2SE应用程序中可能还算正常,但是到了J2EE程序中,一定会出问题!而且这个路径,在不同的服务器中都是不同的!

  相对路径最佳实践

 普通工程推荐使用相对于当前classpath的相对路径


  因此,我们在使用相对路径时,应当使用相对于当前classpath的相对路径。

  ClassLoader类的getResource(String name),getResourceAsStream(String name)等方法,使用相对于当前项目的classpath的相对路径来查找资源。

  读取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此。

  通过查看ClassLoader类及其相关类的源代码,我发现,它实际上还是使用了URI形式的绝对路径。通过得到当前classpath的URI形式的绝对路径,构建了相对路径的URI形式的绝对路径。(这个实际上是猜想,因为JDK内部调用了SUN的源代码,而这些代码不属于JDK,不是开源的。)
  相对路径本质上还是绝对路径

  因此,归根结底,Java本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是一些便利方法。不过是API在底层帮助我们构建了绝对路径,从而找到资源的!

  得到classpath和当前类的绝对路径的一些方法

  下面是一些得到classpath和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。

  1.FileTest.class.getResource("")

  得到的是当前类FileTest.class文件的URI目录。不包括自己!

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/

  2.FileTest.class.getResource("/")

  得到的是当前的classpath的绝对URI路径。

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

  3.Thread.currentThread().getContextClassLoader().getResource("")

  得到的也是当前ClassPath的绝对URI路径。

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

  4.FileTest.class.getClassLoader().getResource("")

  得到的也是当前ClassPath的绝对URI路径。

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

  5.ClassLoader.getSystemResource("")

  得到的也是当前ClassPath的绝对URI路径。

  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

  我推荐使用Thread.currentThread().getContextClassLoader().getResource("")来得到当前的classpath的绝对路径的URI表示法。

  Web应用程序中资源的寻址


  上文中说过,当前用户目录,即相对于System.getProperty("user.dir")返回的路径。

  对于JavaEE服务器,这可能是服务器的某个路径,这个并没有统一的规范! 而不是我们发布的Web应用程序的根目录!

  这样,在Web应用程序中,我们绝对不能使用相对于当前用户目录的相对路径。

 Web应用中ServletContext.getRealPath("/")

得到Web应用程序的根目录的绝对路径。


  这样,我们只需要提供相对于Web应用程序根目录的路径,就可以构建出定位资源的绝对路径。

  这是我们开发Web应用程序时一般所采取的策略。


  Web应用程序,可以作为Web应用程序进行发布和运行。但是,我们也常常会以JavaSE的方式来运行Web应用程序的某个类的main方法。或者,使用JUnit测试。这都需要使用JavaSE的方式来运行。

  这样,我们就无法使用ServletContext.getRealPath("/")方法得到Web应用程序的根目录的绝对路径。

  而JDK提供的ClassLoader类,它的getResource(String name),getResourceAsStream(String name)等方法,使用相对于当前项目的classpath的相对路径来查找资源。

  读取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此。

  它们都只能使用相对路径来读取classpath下的资源,无法定位到classpath外面的资源。

  Classpath外配置文件读取问题


  通用的相对路径解决办法 ,就是“利用classpath的绝对路径,定位所有资源”

  ClassLoader类的getResource("")方法能够得到当前classpath的绝对路径,这是所有Java程序都拥有的能力,具有最大的适应性!
而目前的JDK提供的ClassLoader类的getResource(String 相对路径)方法,只能接受一般的相对路径。这样,使用ClassLoader类的getResource(String 相对路径)方法就只能定位到classpath下的资源。

  如果,它能够接受“../”这样的参数,允许我们用相对路径来定位classpath外面的资源,那么我们就可以定位位置的资源!

  当然,我无法修改ClassLoader类的这个方法,于是,自己写代码实现吧。


  总结:

  1.尽量不要使用相对于System.getProperty("user.dir")当前用户目录的相对路径。这是一颗定时,随时可能要你的命。

  2.尽量使用URI形式的绝对路径资源。它可以很容易的转变为URI,URL,File对象。

  3.尽量使用相对classpath的相对路径。不要使用绝对路径。使用上面ClassLoaderUtil类的public static URL getExtendResource(String relativePath)方法已经能够使用相对于classpath的相对路径定位所有位置的资源。

  4.绝对不要使用硬编码的绝对路径(D:\\***)。因为,我们完全可以使用ClassLoader类的getResource("")方法得到当前classpath的绝对路径。
使用硬编码的绝对路径是完全没有必要的!它一定会让你死的很难看!程序将无法移植!

  如果你一定要指定一个绝对路径,那么使用配置文件,也比硬编码要好得多!

  当然,我还是推荐你使用程序得到classpath的绝对路径来拼资源的绝对路径!

1.如何获得当前文件路径
常用:
字符串类型:System.getProperty("user.dir");
综合:
package com.zcjl.test.base;
import java.io.File;
public class Test {
public static void main(String[] args) throws Exception {
System.out.println(
Thread.currentThread().getContextClassLoader().getResource(""));
System.out.println(Test.class.getClassLoader().getResource(""));
System.out.println(ClassLoader.getSystemResource(""));
System.out.println(Test.class.getResource(""));
System.out.println(Test.class.getResource("/"));

System.out.println(new File("").getAbsolutePath());
System.out.println(System.getProperty("user.dir"));
}
}
file:/E:/workSpace/javaTest/target/classes/
file:/E:/workSpace/javaTest/target/classes/
file:/E:/workSpace/javaTest/target/classes/
file:/E:/workSpace/javaTest/target/classes/javaAPI/
file:/E:/workSpace/javaTest/target/classes/
E:\workSpace\javaTest
E:\workSpace\javaTest

 

2.Web服务中
(1).Weblogic
WebApplication的系统文件根目录是你的weblogic安装所在根目录。
例如:如果你的weblogic安装在c:\bea\weblogic700.....
那么,你的文件根路径就是c:\.
所以,有两种方式能够让你访问你的服务器端的文件:
a.使用绝对路径:
比如将你的参数文件放在c:\yourconfig\yourconf.properties,
直接使用 new FileInputStream("/yourconfig/yourconf.properties");
b.使用相对路径:
相对路径的根目录就是你的webapplication的根路径,即WEB-INF的上一级目录,将你的参数文件放在yourwebapp\yourconfig\yourconf.properties,
这样使用:
new FileInputStream("yourconfig/yourconf.properties");
这两种方式均可,自己选择。
(2).Tomcat
在类中输出System.getProperty("user.dir");显示的是%Tomcat_Home%/bin
(3).Resin
不是你的JSP放的相对路径,是JSP引擎执行这个JSP编译成SERVLET
的路径为根.比如用新建文件法测试File f = new File("a.htm");
这个a.htm在resin的安装目录下
(4).如何读相对路径哪?
在Java文件中getResource或getResourceAsStream均可
例:getClass().getResourceAsStream(filePath);//filePath可以是"/filename",这里的/代表web发布根路径下WEB-INF/classes
也可以getClass().getClassLoader().getResourceAsStream(filePath)//filePath不是带“/”的
(5).获得文件真实路径
string file_real_path=request.getRealPath("mypath/filename");
通常使用request.getRealPath("/");
4.遗留问题
目前new FileInputStream()只会使用绝对路径,相对

InputStream in1 = new FileInputStream("abc1.properties"); // 相对路径
InputStream in2 = new FileInputStream("/abc2.properties"); // 绝对路径,E盘下
InputStream in3 = new FileInputStream("e://abc3.properties"); //绝对路径
5.按Java文件类型分类读取配置文件
配 置文件是应用系统中不可缺少的,可以增加程序的灵活性。java.util.Properties是从jdk1.2就有的类,一直到现在都支持load ()方法,jdk1.4以后save(output,string) ->store(output,string)。如果只是单纯的读,根本不存在烦恼的问题。web层可以通过 Thread.currentThread().getContextClassLoader().
getResourceAsStream("xx.properties") 获取;
Application可以通过new FileInputStream("xx.properties");直接在classes一级获取。关键是有时我们需要通过web修改配置文件,我们不 能将路径写死了。经过测试觉得有以下心得:

 

 

1.servlet中读写。如果运用Struts 或者Servlet可以直接在初始化参数中配置,调用时根据servlet的getRealPath("/")获取真实路径,再根据String file = this.servlet.getInitParameter("abc");获取相对的WEB-INF的相对路径。
例:
InputStream input = Thread.currentThread().getContextClassLoader().
getResourceAsStream("abc.properties");
Properties prop = new Properties();
prop.load(input);
input.close();
OutputStream out = new FileOutputStream(path);
prop.setProperty("abc", “test");
prop.store(out, “–test–");
out.close();
2.直接在jsp中操作,通过jsp内置对象获取可操作的绝对地址。
例:
// jsp页面
String path = pageContext.getServletContext().getRealPath("/");
String realPath = path+"/WEB-INF/classes/abc.properties";
//java 程序
InputStream in = getClass().getClassLoader().getResourceAsStream("abc.properties"); // abc.properties放在webroot/WEB-INF/classes/目录下
prop.load(in);
in.close();
OutputStream out = new FileOutputStream(path); // path为通过页面传入的路径
prop.setProperty("abc", “abcccccc");
prop.store(out, “–test–");
out.close();
3.只通过Java程序操作资源文件
InputStream in = new FileInputStream("abc.properties"); // 相对路径,项目下的路径
OutputStream out = new FileOutputStream("abc.properties");

文章评论

程序员必看的十大电影
程序员必看的十大电影
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
漫画:程序员的工作
漫画:程序员的工作
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员的鄙视链
程序员的鄙视链
我的丈夫是个程序员
我的丈夫是个程序员
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
每天工作4小时的程序员
每天工作4小时的程序员
为什么程序员都是夜猫子
为什么程序员都是夜猫子
鲜为人知的编程真相
鲜为人知的编程真相
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
那些争议最大的编程观点
那些争议最大的编程观点
中美印日四国程序员比较
中美印日四国程序员比较
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
程序员和编码员之间的区别
程序员和编码员之间的区别
程序员都该阅读的书
程序员都该阅读的书
老程序员的下场
老程序员的下场
代码女神横空出世
代码女神横空出世
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
10个调试和排错的小建议
10个调试和排错的小建议
 程序员的样子
程序员的样子
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
我是如何打败拖延症的
我是如何打败拖延症的
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
Java程序员必看电影
Java程序员必看电影
编程语言是女人
编程语言是女人
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
总结2014中国互联网十大段子
总结2014中国互联网十大段子
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
旅行,写作,编程
旅行,写作,编程
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有