SDSteam

导航

JAVA 文件路径的一些问题

 

模拟Hibernate的实现:
   ①顺便研究了一下读文件。
   ②关于路径的问题:
 我们路径 除了绝对路径就是相对路径。如果在项目中使用绝对路径可能容易点,但代码移植就麻烦了,而且容易出错。
 绝对路径:
             要编译性文件(.java) E:/pojectpath/src/mypakage
             在项目中的资源文件,非编译文件(.properties .xml ...) 一般不使用绝对路径
 相对路径:
             要编译性文件(.java)src/mypakage
             资源文件,非编译文件(.properties .xml ...) mypakage

即资源文件找java文件 路径只要包名就够了(不管资源文件在项目中的那个地方)。

资源文件找资源文件:1资源文件找2资源文件,路径由1资源文件所在的当前目录开始往下一级目录找……。
(有待完善!!!)
而java文件找资源文件 由目录src开始。
java文件找java文件,路径由目录src开始。
    在一个项目工程中使用到的文件路径如果不使用绝对路径,表示当工程文件加载时(找该文件)从工程的目录(.poject 当前目录)编译根目录。
    注意:在前期java文件编译时路径。即需要系统路径(当然IDE 做了一些处理,如eclipse 把硬盘到工程目录自动加上了。 src 就得程序员手动加了) 在编译后成 .class文件时。就会把系统路径去掉。当然包括eclipse的src目录。对于其他IDE基本上也是这样。但是如果我们那就意味着一旦脱离IDE工具系统就找不到我们上面给出相对路径的文件了。
    也就是说:当项目中的文件路径用到相对路径时,在编译时IDE工具为这些相对路径加上了硬盘到工程目录,而后形成了文件的绝对路径。
在编译后成 .class文件时,就会把系统路径去掉。说到这里问题就来了如果我们别人需要运行我们的工程(这些工程中含有读取资源文件的语句),一种是别人有IDE工具,而我们的工程也是原始工程(不是.jar包,.class字节),那别人可以直接导入IDE然后运行,根据上面的概述
这里不会出错。如果换成控制台执行,那么使用了项目相对路径的读取方式会失败,原因是,此时已经脱离了项目的开发环境(没有把硬盘到工程目录自动加上了,不管是相对路径还是绝对路径最终必须都是以绝对路径找到文件),-----这个问题常常困扰着一些菜鸟,代码在开发工具好好的,发布后执行就失败了!
  
 为了解决上面的问题,我们必须通过获取CLASSPATH,然后通过CLASSPATH找到文件。
一般用于读取配置文件,资源文件……。

 如果需要读取文件我们应该用以下方式:

 这里必须以“/”开头;TA的原理是先取得ReadFile的classpath路径,然后在添加上括号里面的那一部分,最后形成一个文件的绝对路径。
 其内部实现也很简单。
 一个类如果要读项目内的资源文件,我们就可以采用上面这种方面。
 而不是使用 File f = new File("绝对路径"); 或者是File f = new File("相对路径");
 然后FileReader fr = new FileReader(f); fr.read();这样的写法是错误的。
 xx.class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取。其只是通过path构造一个绝对路径,最终还是由 ClassLoader获取资源。

要读取的资源文件要么和 类.class在同一目录下,要么 类.class 的子目录下。
①要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类me.class ,同时有资源文件myfile.xml
那么,应该有如下代码: me.class.getResourceAsStream("myfile.xml");
②而如果资源文件.class文件的子目录下:com.x.y 下有类me.class ,同时有资源文件cont.c.n,而cont.c.n下有资源文件myfile.xml
代码可以为: me.class.getResourceAsStream("/cont/c/n/myfile.xml"); 或 me.class.getResourceAsStream("cont/c/n/myfile.xml"); 这里有一个问题:关于me.class.getResourceAsStream("/cont/c/n/myfile.xml");是不是到工程目录中去获取这个资源文件了。

所以当我们编写时要注意资源文件在src中的位置。要么TA和那个类在同一个目录下,要么在类的子目录下。
总结:
①通过xx.class.getResource("");
  xx.class.getResource("").getFile();
  xx.class.getResource("/").getFile()
  这两种方法都获取了xx.class文件所在目录的绝对路径外加/.
  对于使用上面的方法找资源文件:其资源文件要么与xx.class文件在同一目录下,对于这种情况我们可以采用xx.class.getResource("文件名.扩展名").getFile();获取文件的绝对路径。要么在xx.class目录的子目录下,我们可以采用
xx.class.getResource("/xx/yy/filename.filetype").getFile(); 和 xx.class.getResource("xx/yy/filename.filetype").getFile();方法获取。注意对于这种方法资源文件要么和xx.class文件在同一目录,要么在xx.class的子目录下,如果资源文件在其他地方这种方法将无法找到文件。
  调用了getFile()和不调用getFile()的区别:
  加了返回的文件名:
  /C:/Documents%20and%20Settings/Administrator/workspace/Simulate_Hibernate_001/bin/
  不加返回的文件名为:
  file:/C:/Documents%20and%20Settings/Administrator/workspace/Simulate_Hibernate_001/bin/
  注意前面多了一个file:
 
②xx(类名).class.getClassLoader().getResource("");//获取JAVA编译后.class文件或其他资源文件存放的bin文件夹的路径。也就是在.classpath文件中<classpathentry kind="output" path="bin"/> bin文件夹的绝对路径。
   要获取bin目录下的文件路径可以通过:xx(类名).class.getClassLoader().getResource("filename.filetype"); 而要获取bin目录子目录下的文件路径可以通过xx(类名).class.getClassLoader().getResource("xx/yy/……/filename.filetype");
  对于xx(类名).class.getClassLoader()我们也可以使用
  Configuration.class.getClassLoader().getResourceAsStream("com/testpath/hibernate/subaolei.txt");方法获取文件路径的同时new一个文件流并返回。

一般来说我们使用的是第一种方法。
使用CLASSPATH路径是可靠的。
对于程序要读取的文件,尽可能放到CLASSPATH下,这样就能保证在开发和发布时候均正常读取。

posted on 2012-04-11 11:21  SDSteam  阅读(1058)  评论(0编辑  收藏  举报