java文件路径操作详细

  1. Java的路径问题,非常难搞。最近的工作涉及到创建和读取文件的工作,这里我就给大家彻底得解决Java路径问 题。   
  2.   
  3.   我编写了一个方法,比 ClassLoader.getResource(String 相对路径)方法的能力更强。它可以接受“../”这样的参数,允许我们用相对路径来定位 classpath外面的资源。这样,我们就可以使用相对于classpath的路径,定位所有位置的资源!   
  4.   
  5.    Java路径   
  6.   
  7.   Java中使用的路径,分为两 种:绝对路径和相对路径。具体而言,又分为四种:   
  8.   
  9.    一、URI形式的绝对资源路径   
  10.   
  11.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b   
  12.   
  13.    URL是URI的特例。URL的前缀/协议,必须是Java认识的。URL可以打开资源,而URI则不行。   
  14.   
  15.    URL和URI对象可以互相转换,使用各自的toURI(),toURL()方法即可!   
  16.   
  17.    二、本地系统的绝对路径   
  18.   
  19.    D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b   
  20.   
  21.    Java.io包中的类,需要使用这种形式的参数。   
  22.   
  23.    但是,它们一般也提供了URI类型的参数,而URI类型的参数,接受的是URI样式的String。因此,通过URI转换,还是可以把URI样式的绝对 路径用在java.io包中的类中。   
  24.   
  25.   三、相对 于classpath的相对路径   
  26.   
  27.   如:相对 于   
  28.   
  29.   file:/D:/java /eclipse32/workspace/jbpmtest3/bin/这个路径的相对路径。其中,bin是本项目的classpath。所有的 Java源文件编译后的.class 文件复制到这个目录中。   
  30.   
  31.    四、相对于当前用户目录的相对路径   
  32.   
  33.   就是相对 于System.getProperty("user.dir" )返回的路 径。   
  34.   
  35.   对于一般项目,这是项目的 根路径。对于JavaEE服务器,这可能是服务器的某个路径。这个并没有统一的规范!   
  36.   
  37.    所以,绝对不要使用“相对于当前用户目录的相对路径”。然而:   
  38.   
  39.    默认情况下,java.io 包中的类总是根据当前用户目录来分析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的 调用目录。   
  40.   
  41.   这就是说,在使用java.io包 中的类时,最好不要使用相对路径。否则,虽然在J2SE应用程序中可能还算正常,但是到了J2EE程序中,一定会出问题!而且这个路径,在不同的服务器中 都是不同的!   
  42.   
  43.   相对路径最佳实践   
  44.   
  45.    推荐使用相对于当前classpath的相对路径   
  46.   
  47.    因此,我们在使用相对路径时,应当使用相对于当前classpath的相对路径。   
  48.   
  49.    ClassLoader类的getResource(String name),getResourceAsStream(String name)等 方法,使用相对于当前项目的classpath的相对路径来查找资源。   
  50.   
  51.    读取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此。   
  52.   
  53.    通过查看ClassLoader类及其相关类的源代码,我发现,它实际上还是使用了URI形式的绝对路径。通过得到当前classpath的URI形式 的绝对路径,构建了相对路径的URI形式的绝对路径。(这个实际上是猜想,因为JDK内部调用了SUN的源代码,而这些代码不属于JDK,不是开源 的。)   
  54.   相对路径本质上还是绝对路径   
  55.   
  56.    因此,归根结底,Java本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是一些便利方法。不过是API在底层帮助我们构建了 绝对路径,从而找到资源的!   
  57.   
  58.   得到 classpath和当前类的绝对路径的一些方法   
  59.   
  60.    下面是一些得到classpath和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。   
  61.   
  62.    1 .FileTest. class .getResource( "" )   
  63.   
  64.    得到的是当前类FileTest.class 文件的URI目录。不包括自 己!   
  65.   
  66.   如:file:/D: /java/eclipse32/workspace/jbpmtest3/bin/com/test/   
  67.   
  68.    2 .FileTest. class .getResource( "/" )   
  69.   
  70.    得到的是当前的classpath的绝对URI路径。   
  71.   
  72.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/   
  73.   
  74.    3 .Thread.currentThread().getContextClassLoader().getResource( "" )   
  75.   
  76.    得到的也是当前ClassPath的绝对URI路径。   
  77.   
  78.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/   
  79.   
  80.    4 .FileTest. class .getClassLoader().getResource( "" )   
  81.   
  82.    得到的也是当前ClassPath的绝对URI路径。   
  83.   
  84.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/   
  85.   
  86.    5 .ClassLoader.getSystemResource( "" )   
  87.   
  88.    得到的也是当前ClassPath的绝对URI路径。   
  89.   
  90.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/   
  91.   
  92.    我推荐使用Thread.currentThread().getContextClassLoader().getResource("" )来得到当前的classpath的绝对路径的URI表示法。   
  93.   
  94.    Web应用程序中资源的寻址   
  95.   
  96.   上文中说过,当 前用户目录,即相对于System.getProperty("user.dir" ) 返回的路径。   
  97.   
  98.   对于JavaEE 服务器,这可能是服务器的某个路径,这个并没有统一的规范!   
  99.   
  100.    而不是我们发布的Web应用程序的根目录!   
  101.   
  102.    这样,在Web应用程序中,我们绝对不能使用相对于当前用户目录的相对路径。   
  103.   
  104.    在Web应用程序中,我们一般通过ServletContext.getRealPath("/" ) 方法得到Web应用程序的根目录的绝对路径。   
  105.   
  106.    这样,我们只需要提供相对于Web应用程序根目录的路径,就可以构建出定位资源的绝对路径。   
  107.   
  108.    这是我们开发Web应用程序时一般所采取的策略。   
  109.   
  110.   
  111.    Web应用程序,可以作为Web应用程序进行发布和运行。但是,我们也常常会以JavaSE的方式来运行Web应用程序的某个类的main方法。或者, 使用JUnit测试。这都需要使用JavaSE的方式来运行。   
  112.   
  113.    这样,我们就无法使用ServletContext.getRealPath("/" ) 方法得到Web应用程序的根目录的绝对路径。   
  114.   
  115.    而JDK提供的ClassLoader类,它的 getResource(String name),getResourceAsStream(String name)等方法,使用相对于当前项目的 classpath的相对路径来查找资源。   
  116.   
  117.   读 取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此。   
  118.   
  119.    它们都只能使用相对路径来读取classpath下的资源,无法定位到classpath外面的资源。   
  120.   
  121.    Classpath外配置文件读取问题   
  122.   
  123.   如, 我们使用测试驱动开发的方法,开发Spring、Hibernate、iBatis等使用配置文件的Web应用程序,就会遇到问题。   
  124.   
  125.    尽管Spring自己提供了FileSystem(也就是相对于user,dir目录)来读取Web配置文件的方法,但是终究不是很方便。而且与Web 程序中的代码使用方式不一致!   
  126.   
  127.   至于 Hibernate,iBatis就更麻烦了!只有把配置文件移到classpath下,否则根本不可能使用测试驱动开发!   
  128.   
  129.    这怎么办?   
  130.   
  131.   通用的相对路径解决办法   
  132.   
  133.    面对这个问题,我决定编写一个助手类ClassLoaderUtil,提供一个便利方法[public   static  URL getExtendResource(String relativePath)]。 在Web应用程序等一切Java程序中,需要定位classpath外的资源时,都使用这个助手类的便利方法,而不使用Web应用程序特有的 ServletContext.getRealPath( "/" ) 方法来定位资源。   
  134.   
  135.   利用 classpath的绝对路径,定位所有资源   
  136.   
  137.    这个便利方法的实现原理,就是“利用classpath的绝对路径,定位所有资源”。   
  138.   
  139.    ClassLoader类的getResource("" )方法能够得到当前 classpath的绝对路径,这是所有Java程序都拥有的能力,具有最大的适应性!   
  140. 而 目前的JDK提供的ClassLoader类的getResource(String 相对路径)方法,只能接受一般的相对路径。这样,使用 ClassLoader类的getResource(String 相对路径)方法就只能定位到classpath下的资源。   
  141.   
  142.    如果,它能够接受“../”这样的参数,允许我们用相对路径来定位classpath外面的资源,那么我们就可以定位位置的资源!   
  143.   
  144.    当然,我无法修改ClassLoader类的这个方法,于是,我编写了一个助手类ClassLoaderUtil类,提供了[public   static  URL getExtendResource(String relativePath)] 这个方法。它能够接受带有“../”符号的相对路径,实现了自由寻找资源的功能。   
  145.   
  146.    通过相对classpath路径实现自由寻找资源的助手类的源代码:   
  147. import  java.io.IOException;   
  148. import  java.io.InputStream;   
  149. import  java.net.MalformedURLException;   
  150. import  java.net.URL;   
  151. import  java.util.Properties;   
  152.   
  153. import  org.apache.commons.logging.Log;   
  154. import  org.apache.commons.logging.LogFactory;   
  155.   
  156. /**   
  157. *@author 沈东良shendl_s@hotmail.com   
  158. *Nov29,2006 10:34:34AM   
  159. *用来加载类,classpath下的资源文件,属性文件等。   
  160. *getExtendResource(StringrelativePath)方法,可以使用../符号来加载 classpath外部的资源。   
  161. */    
  162. publicclass ClassLoaderUtil {   
  163.   privatestatic Log log=LogFactory.getLog(ClassLoaderUtil.class );   
  164.  /**   
  165.   *Thread.currentThread().getContextClassLoader().getResource("")   
  166.  */    
  167.   
  168.  /**   
  169.   *加载Java类。 使用全限定类名   
  170.   *@paramclassName   
  171.   *@return   
  172.  */    
  173.   publicstatic Class loadClass(String className) {   
  174.    try  {   
  175.     return  getClassLoader().loadClass(className);   
  176.    } catch  (ClassNotFoundException e) {   
  177.     thrownew RuntimeException("class not found '" +className+ "'" , e);   
  178.    }   
  179.  }   
  180.  /**   
  181.   *得到类加载器   
  182.  *@return   
  183.  */    
  184.   publicstatic ClassLoader getClassLoader() {   
  185.   return  ClassLoaderUtil. class .getClassLoader();   
  186.   }   
  187.  /**   
  188.  *提供相对于classpath的资源路径,返回文件的输入流   
  189.  *@paramrelativePath必须传递资源的相对路径。是相对于classpath的路径。如果需要查找 classpath外部的资源,需要使用 ../来查找   
  190.  *@return 文件输入流   
  191.  *@throwsIOException   
  192.  *@throwsMalformedURLException   
  193.  */    
  194.   publicstatic InputStream getStream(String relativePath) throws  MalformedURLException, IOException {   
  195.    if (!relativePath.contains( "../" )){   
  196.    return  getClassLoader().getResourceAsStream(relativePath);   
  197.    }else {   
  198.     return  ClassLoaderUtil.getStreamByExtendResource(relativePath);   
  199.    }   
  200.  }   
  201.  /**   
  202.   *   
  203.  *@paramurl   
  204.  *@return   
  205.  *@throwsIOException   
  206.  */    
  207.   publicstatic InputStream getStream(URL url) throws  IOException{   
  208.    if (url!= null ){   
  209.     return  url.openStream();   
  210.    }else {   
  211.     returnnull;   
  212.   }   
  213.  }   
  214.  /**   
  215.   *   
  216.   *@paramrelativePath必须传递资源的相对路径。是相对于classpath的路径。如果需要查找classpath外部的资源,需要使 用 ../来查找   
  217.  *@return   
  218.  *@throwsMalformedURLException   
  219.  *@throwsIOException   
  220.  */    
  221.   publicstatic InputStream getStreamByExtendResource(String relativePath) throws  MalformedURLException, IOException{   
  222.    return  ClassLoaderUtil.getStream(ClassLoaderUtil.getExtendResource(relativePath));   
  223.   }   
  224.   
  225.  /**   
  226.  *提供相对于classpath的资源路径,返回属性对象,它是一个散列表   
  227.  *@paramresource   
  228.  *@return   
  229.  */    
  230.   publicstatic Properties getProperties(String resource) {   
  231.    Properties properties = new  Properties();   
  232.    try  {   
  233.     properties.load(getStream(resource));   
  234.   } catch  (IOException e) {   
  235.     thrownew RuntimeException("couldn't load properties file '" +resource+ "'" , e);   
  236.    }   
  237.   return  properties;   
  238.   }   
  239.  /**   
  240.  *得到本Class所在的ClassLoader的Classpat的绝对路径。   
  241.  *URL形式的   
  242.  *@return   
  243.  */    
  244.   publicstatic String getAbsolutePathOfClassLoaderClassPath(){   
  245.    ClassLoaderUtil.log.info(ClassLoaderUtil.getClassLoader().getResource("" ).toString());   
  246.    return  ClassLoaderUtil.getClassLoader().getResource( "" ).toString();   
  247.   }   
  248.  /**   
  249.  *   
  250.   *@paramrelativePath 必须传递资源的相对路径。是相对于classpath的路径。如果需要查找classpath外部的资源,需要 使 用../来查找   
  251.  *@return资 源的绝对URL   
  252.   *@throwsMalformedURLException   
  253.  */    
  254.   publicstatic URL getExtendResource(String relativePath) throws  MalformedURLException{   
  255.    ClassLoaderUtil.log.info("传入的相对路径:" +relativePath) ;   
  256.    //ClassLoaderUtil.log.info(Integer.valueOf(relativePath.indexOf("../"))) ;    
  257.    if (!relativePath.contains( "../" )){   
  258.    return  ClassLoaderUtil.getResource(relativePath);   
  259.    }   
  260.    String classPathAbsolutePath=ClassLoaderUtil.getAbsolutePathOfClassLoaderClassPath();   
  261.    if (relativePath.substring( 01 ).equals( "/" )){   
  262.     relativePath=relativePath.substring(1 );   
  263.    }   
  264.    ClassLoaderUtil.log.info(Integer.valueOf(relativePath.lastIndexOf("../" ))) ;   
  265.    String wildcardString=relativePath.substring(0 ,relativePath.lastIndexOf( "../" )+ 3 );   
  266.    relativePath=relativePath.substring(relativePath.lastIndexOf("../" )+ 3 );   
  267.    int  containSum=ClassLoaderUtil.containSum(wildcardString,  "../" );   
  268.    classPathAbsolutePath= ClassLoaderUtil.cutLastString(classPathAbsolutePath, "/" , containSum);   
  269.    String resourceAbsolutePath=classPathAbsolutePath+relativePath;   
  270.    ClassLoaderUtil.log.info("绝对路径:" +resourceAbsolutePath) ;   
  271.    URL resourceAbsoluteURL=new  URL(resourceAbsolutePath);   
  272.    return  resourceAbsoluteURL;   
  273.   }   
  274.  /**   
  275.  *   
  276.   *@paramsource   
  277.   *@paramdest   
  278.   *@return   
  279.  */    
  280.   privatestaticint containSum(String source,String dest){   
  281.    int  containSum= 0 ;   
  282.   int  destLength=dest.length();   
  283.    while (source.contains(dest)){   
  284.     containSum=containSum+1 ;   
  285.     source=source.substring(destLength);   
  286.   }   
  287.    return  containSum;   
  288.   }   
  289.  /**   
  290.  *   
  291.   *@paramsource   
  292.   *@paramdest   
  293.   *@paramnum   
  294.   *@return   
  295.  */    
  296.   privatestatic String cutLastString(String source,String dest,int  num){   
  297.   // String cutSource=null;    
  298.    for ( int  i= 0 ;i<num;i++){   
  299.     source=source.substring(0 , source.lastIndexOf(dest, source.length()- 2 )+ 1 );   
  300.    }   
  301.   return  source;   
  302.   }   
  303.  /**   
  304.  *   
  305.   *@paramresource   
  306.   *@return   
  307.  */    
  308.   publicstatic URL getResource(String resource){   
  309.    ClassLoaderUtil.log.info("传入的相对于classpath的路径:" +resource) ;   
  310.    return  ClassLoaderUtil.getClassLoader().getResource(resource);   
  311.   }   
  312.  /**   
  313.  *@paramargs   
  314.  *@throwsMalformedURLException   
  315.  */    
  316.   publicstaticvoid main(String[] args) throws  MalformedURLException {   
  317.    //ClassLoaderUtil.getExtendResource("../spring/dao.xml");    
  318.    //ClassLoaderUtil.getExtendResource("../../../src/log4j.properties");    
  319.    ClassLoaderUtil.getExtendResource("log4j.properties" );   
  320.    System.out.println(ClassLoaderUtil.getClassLoader().getResource("log4j.properties" ).toString());   
  321.   }   
  322. }   
  323.   
  324.    后记   
  325.   
  326.   ClassLoaderUtil类的public   static  URL getExtendResource(String relativePath), 虽然很简单,但是确实可以解决大问题。   
  327.   
  328.    不过这个方法还是比较简陋的。我还想在未来有空时,进一步增强它的能力。比如,增加Ant风格的匹配符。用**代表多个目录,*代表多个字符,?代表一 个字符。达到Spring那样的能力,一次返回多个资源的URL,进一步方便大家开发。   
  329.   
  330.    总结:   
  331.   
  332.   1 .尽量不要使用相对于System.getProperty( "user.dir" )当前用户目录的相对路径。   
  333.   
  334.    2 .尽量使用URI形式的绝对路径资源。它可以很容易的转变为 URI,URL,File对象。   
  335.   
  336.    3 .尽量使用相对classpath的相对路径。不要使用绝对路径。使用上面 ClassLoaderUtil类的 public   static  URL getExtendResource(String relativePath) 方法已经能够使用相对于classpath的相对路径定位所有位置的资源。   
  337.   
  338.    4 .绝对不要使用硬编码的绝对路径。因为,我们完全可以使用 ClassLoader类的getResource( "" )方法得 到当前classpath的绝对路径。   
  339. 使用硬编码的绝对路径是完全没有必要的!它一定 会让你死的很难看!程序将无法移植!   
  340.   
  341.   如果你一 定要指定一个绝对路径,那么使用配置文件,也比硬编码要好得多!   
  342.   
  343.    当然,我还是推荐你使用程序得到classpath的绝对路径来拼资源的绝对路径!   
  344.   
  345. 1 .如何获得当前文件路径   
  346. 常 用:   
  347. 字符串类型:System.getProperty("user.dir" );   
  348. 综 合:   
  349. package  com.zcjl.test.base;   
  350. import  java.io.File;   
  351. public   class  Test {   
  352.     public   static   void  main(String[] args)  throws  Exception {   
  353.         System.out.println(   
  354.             Thread.currentThread().getContextClassLoader().getResource("" ));   
  355.         System.out.println(Test.class .getClassLoader().getResource( "" ));   
  356.         System.out.println(ClassLoader.getSystemResource("" ));   
  357.         System.out.println(Test.class .getResource( "" ));   
  358.         System.out.println(Test.class .getResource( "/" ));   
  359.   
  360.         System.out.println(new  File( "" ).getAbsolutePath());   
  361.         System.out.println(System.getProperty("user.dir" ));   
  362.     }   
  363. }   
  364. file:/E:/workSpace/javaTest/target/classes/   
  365. file:/E:/workSpace/javaTest/target/classes/   
  366. file:/E:/workSpace/javaTest/target/classes/   
  367. file:/E:/workSpace/javaTest/target/classes/javaAPI/   
  368. file:/E:/workSpace/javaTest/target/classes/   
  369. E:/workSpace/javaTest   
  370. E:/workSpace/javaTest   
  371.   
  372. 2 .Web服务中   
  373. (1 ).Weblogic   
  374. WebApplication 的系统文件根目录是你的weblogic安装所在根目录。   
  375. 例如:如果你的weblogic安装在 c:/bea/weblogic700.....   
  376. 那么,你的文件根路径就是c:/.   
  377. 所 以,有两种方式能够让你访问你的服务器端的文件:   
  378. a.使用绝对路径:   
  379. 比 如将你的参数文件放在c:/yourconfig/yourconf.properties,   
  380. 直接使 用 new  FileInputStream( "/yourconfig/yourconf.properties" );   
  381. b. 使用相对路径:   
  382. 相对路径的根目录就是你的webapplication的根路径,即WEB-INF的 上一级目录,将你的参数文件放在yourwebapp/yourconfig/yourconf.properties,   
  383. 这 样使用:   
  384. new  FileInputStream( "yourconfig/yourconf.properties" );   
  385. 这 两种方式均可,自己选择。   
  386. (2 ).Tomcat   
  387. 在 类中输出System.getProperty("user.dir" );显示的 是%Tomcat_Home%/bin   
  388. (3 ).Resin   
  389. 不 是你的JSP放的相对路径,是JSP引擎执行这个JSP编译成SERVLET   
  390. 的路径为根.比如用新建 文件法测试File f = new  File( "a.htm" );   
  391. 这个 a.htm在resin的安装目录下   
  392. (4 ). 如何读相对路径哪?   
  393. 在Java文件中getResource或 getResourceAsStream均可   
  394. 例:getClass().getResourceAsStream(filePath);//filePath可以是"/filename",这里的/代表web发布根路径下WEB-INF /classes    
  395. 也可以 getClass().getClassLoader().getResourceAsStream(filePath)//filePath不是带“/”的    
  396. (5 ).获得文件真实路径   
  397. string  file_real_path=request.getRealPath("mypath/filename" );    
  398. 通 常使用request.getRealPath("/" );    
  399. 4 .遗留问题   
  400. 目前new  FileInputStream()只会使用绝对路径,相对   
  401.   
  402.   InputStream in1 = new  FileInputStream( "abc1.properties" );  // 相对路径    
  403.   InputStream in2 = new  FileInputStream( "/abc2.properties" );  // 绝对路径,E盘下    
  404.   InputStream in3 = new  FileInputStream( "e://abc3.properties" ); //相对路径   
  405. 5 .按Java文件类型分类读取配置文件   
  406. 配 置 文件是应用系统中不可缺少的,可以增加程序的灵活性。java.util.Properties是从jdk1.2 就 有的类,一直到现在都支持load ()方法,jdk1. 4 以后 save(output,string) ->store(output,string)。如果只是单纯的读,根本不存在烦恼的问题。web层可以 通过 Thread.currentThread().getContextClassLoader().   
  407. getResourceAsStream("xx.properties" ) 获取;   
  408. Application 可以通过new  FileInputStream( "xx.properties" );直接在classes一级获取。关键是有时我们需要通过 web修改配置文件,我们不 能将路径写死了。经过测试觉得有以下心得:   
  409. 1 .servlet中读写。如果运用Struts 或者Servlet可以直接在初始化参数中 配置,调用时根据servlet的getRealPath( "/" ) 获取真实路径,再根据String file =  this .servlet.getInitParameter( "abc" );获取相对的WEB-INF的相对路径。   
  410. 例:   
  411. InputStream input = Thread.currentThread().getContextClassLoader().   
  412. getResourceAsStream("abc.properties" );   
  413. Properties prop = new  Properties();   
  414. prop.load(input);   
  415. input.close();   
  416. OutputStream out = new  FileOutputStream(path);   
  417. prop.setProperty("abc" , “test");   
  418. prop.store(out, “–test–");   
  419. out.close();   
  420. 2 .直接在jsp中操作,通过jsp内置对象获取可操作的绝对地址。   
  421. 例:   
  422. // jsp页面    
  423. String path = pageContext.getServletContext().getRealPath("/" );   
  424. String realPath = path+"/WEB-INF/classes/abc.properties" ;   
  425. //java 程序    
  426. InputStream in = getClass().getClassLoader().getResourceAsStream("abc.properties" );  // abc.properties放在webroot/WEB-INF/classes/目录下    
  427. prop.load(in);   
  428. in.close();   
  429. OutputStream out = new  FileOutputStream(path);  // path为通过页面传入的路径    
  430. prop.setProperty("abc" , “abcccccc");   
  431. prop.store(out, “–test–");   
  432. out.close();   
  433. 3 .只通过Java程序操作资源文件   
  434. InputStream in = new  FileInputStream( "abc.properties" );  // 相对路径,项目下的路径    
  435. OutputStream out = new  FileOutputStream( "abc.properties" );   
  436. Java 的路径问题,非常难搞。最近的工作涉及到创建和读取文件的工作,这里我就给大家彻底得解决Java路径问题。   
  437.   
  438.    我编写了一个方法,比ClassLoader.getResource(String 相对路径)方法的能力更强。它可以接受“../”这样的参数,允 许我们用相对路径来定位classpath外面的资源。这样,我们就可以使用相对于classpath的路径,定位所有位置的资源!   
  439.   
  440.    Java路径   
  441.   
  442.   Java中使用的路径,分为两 种:绝对路径和相对路径。具体而言,又分为四种:   
  443.   
  444.    一、URI形式的绝对资源路径   
  445.   
  446.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b   
  447.   
  448.    URL是URI的特例。URL的前缀/协议,必须是Java认识的。URL可以打开资源,而URI则不行。   
  449.   
  450.    URL和URI对象可以互相转换,使用各自的toURI(),toURL()方法即可!   
  451.   
  452.    二、本地系统的绝对路径   
  453.   
  454.    D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b   
  455.   
  456.    Java.io包中的类,需要使用这种形式的参数。   
  457.   
  458.    但是,它们一般也提供了URI类型的参数,而URI类型的参数,接受的是URI样式的String。因此,通过URI转换,还是可以把URI样式的绝对 路径用在java.io包中的类中。   
  459.   
  460.   三、相对 于classpath的相对路径   
  461.   
  462.   如:相对 于   
  463.   
  464.   file:/D:/java /eclipse32/workspace/jbpmtest3/bin/这个路径的相对路径。其中,bin是本项目的classpath。所有的 Java源文件编译后的.class 文件复制到这个目录中。   
  465.   
  466.    四、相对于当前用户目录的相对路径   
  467.   
  468.   就是相对 于System.getProperty("user.dir" )返回的路 径。   
  469.   
  470.   对于一般项目,这是项目的 根路径。对于JavaEE服务器,这可能是服务器的某个路径。这个并没有统一的规范!   
  471.   
  472.    所以,绝对不要使用“相对于当前用户目录的相对路径”。然而:   
  473.   
  474.    默认情况下,java.io 包中的类总是根据当前用户目录来分析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的 调用目录。   
  475.   
  476.   这就是说,在使用java.io包 中的类时,最好不要使用相对路径。否则,虽然在J2SE应用程序中可能还算正常,但是到了J2EE程序中,一定会出问题!而且这个路径,在不同的服务器中 都是不同的!   
  477.   
  478.   相对路径最佳实践   
  479.   
  480.    推荐使用相对于当前classpath的相对路径   
  481.   
  482.    因此,我们在使用相对路径时,应当使用相对于当前classpath的相对路径。   
  483.   
  484.    ClassLoader类的getResource(String name),getResourceAsStream(String name)等 方法,使用相对于当前项目的classpath的相对路径来查找资源。   
  485.   
  486.    读取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此。   
  487.   
  488.    通过查看ClassLoader类及其相关类的源代码,我发现,它实际上还是使用了URI形式的绝对路径。通过得到当前classpath的URI形式 的绝对路径,构建了相对路径的URI形式的绝对路径。(这个实际上是猜想,因为JDK内部调用了SUN的源代码,而这些代码不属于JDK,不是开源 的。)   
  489.   相对路径本质上还是绝对路径   
  490.   
  491.    因此,归根结底,Java本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是一些便利方法。不过是API在底层帮助我们构建了 绝对路径,从而找到资源的!   
  492.   
  493.   得到 classpath和当前类的绝对路径的一些方法   
  494.   
  495.    下面是一些得到classpath和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。   
  496.   
  497.    1 .FileTest. class .getResource( "" )   
  498.   
  499.    得到的是当前类FileTest.class 文件的URI目录。不包括自 己!   
  500.   
  501.   如:file:/D: /java/eclipse32/workspace/jbpmtest3/bin/com/test/   
  502.   
  503.    2 .FileTest. class .getResource( "/" )   
  504.   
  505.    得到的是当前的classpath的绝对URI路径。   
  506.   
  507.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/   
  508.   
  509.    3 .Thread.currentThread().getContextClassLoader().getResource( "" )   
  510.   
  511.    得到的也是当前ClassPath的绝对URI路径。   
  512.   
  513.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/   
  514.   
  515.    4 .FileTest. class .getClassLoader().getResource( "" )   
  516.   
  517.    得到的也是当前ClassPath的绝对URI路径。   
  518.   
  519.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/   
  520.   
  521.    5 .ClassLoader.getSystemResource( "" )   
  522.   
  523.    得到的也是当前ClassPath的绝对URI路径。   
  524.   
  525.    如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/   
  526.   
  527.    我推荐使用Thread.currentThread().getContextClassLoader().getResource("" )来得到当前的classpath的绝对路径的URI表示法。   
  528.   
  529.    Web应用程序中资源的寻址   
  530.   
  531.   上文中说过,当 前用户目录,即相对于System.getProperty("user.dir" ) 返回的路径。   
  532.   
  533.   对于JavaEE 服务器,这可能是服务器的某个路径,这个并没有统一的规范!   
  534.   
  535.    而不是我们发布的Web应用程序的根目录!   
  536.   
  537.    这样,在Web应用程序中,我们绝对不能使用相对于当前用户目录的相对路径。   
  538.   
  539.    在Web应用程序中,我们一般通过ServletContext.getRealPath("/" ) 方法得到Web应用程序的根目录的绝对路径。   
  540.   
  541.    这样,我们只需要提供相对于Web应用程序根目录的路径,就可以构建出定位资源的绝对路径。   
  542.   
  543.    这是我们开发Web应用程序时一般所采取的策略。   
  544.   
  545.   
  546.    Web应用程序,可以作为Web应用程序进行发布和运行。但是,我们也常常会以JavaSE的方式来运行Web应用程序的某个类的main方法。或者, 使用JUnit测试。这都需要使用JavaSE的方式来运行。   
  547.   
  548.    这样,我们就无法使用ServletContext.getRealPath("/" ) 方法得到Web应用程序的根目录的绝对路径。   
  549.   
  550.    而JDK提供的ClassLoader类,它的 getResource(String name),getResourceAsStream(String name)等方法,使用相对于当前项目的 classpath的相对路径来查找资源。   
  551.   
  552.   读 取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此。   
  553.   
  554.    它们都只能使用相对路径来读取classpath下的资源,无法定位到classpath外面的资源。   
  555.   
  556.    Classpath外配置文件读取问题   
  557.   
  558.   如, 我们使用测试驱动开发的方法,开发Spring、Hibernate、iBatis等使用配置文件的Web应用程序,就会遇到问题。   
  559.   
  560.    尽管Spring自己提供了FileSystem(也就是相对于user,dir目录)来读取Web配置文件的方法,但是终究不是很方便。而且与Web 程序中的代码使用方式不一致!   
  561.   
  562.   至于 Hibernate,iBatis就更麻烦了!只有把配置文件移到classpath下,否则根本不可能使用测试驱动开发!   
  563.   
  564.    这怎么办?   
  565.   
  566.   通用的相对路径解决办法   
  567.   
  568.    面对这个问题,我决定编写一个助手类ClassLoaderUtil,提供一个便利方法[public   static  URL getExtendResource(String relativePath)]。 在Web应用程序等一切Java程序中,需要定位classpath外的资源时,都使用这个助手类的便利方法,而不使用Web应用程序特有的 ServletContext.getRealPath( "/" ) 方法来定位资源。   
  569.   
  570.   利用 classpath的绝对路径,定位所有资源   
  571.   
  572.    这个便利方法的实现原理,就是“利用classpath的绝对路径,定位所有资源”。   
  573.   
  574.    ClassLoader类的getResource("" )方法能够得到当前 classpath的绝对路径,这是所有Java程序都拥有的能力,具有最大的适应性!   
  575. 而 目前的JDK提供的ClassLoader类的getResource(String 相对路径)方法,只能接受一般的相对路径。这样,使用 ClassLoader类的getResource(String 相对路径)方法就只能定位到classpath下的资源。   
  576.   
  577.    如果,它能够接受“../”这样的参数,允许我们用相对路径来定位classpath外面的资源,那么我们就可以定位位置的资源!   
  578.   
  579.    当然,我无法修改ClassLoader类的这个方法,于是,我编写了一个助手类ClassLoaderUtil类,提供了[public   static  URL getExtendResource(String relativePath)] 这个方法。它能够接受带有“../”符号的相对路径,实现了自由寻找资源的功能。   
  580.   
  581.    通过相对classpath路径实现自由寻找资源的助手类的源代码:   
  582. import  java.io.IOException;   
  583. import  java.io.InputStream;   
  584. import  java.net.MalformedURLException;   
  585. import  java.net.URL;   
  586. import  java.util.Properties;   
  587.   
  588. import  org.apache.commons.logging.Log;   
  589. import  org.apache.commons.logging.LogFactory;   
  590.   
  591. /**   
  592. *@author 沈东良shendl_s@hotmail.com   
  593. *Nov29,2006 10:34:34AM   
  594. *用来加载类,classpath下的资源文件,属性文件等。   
  595. *getExtendResource(StringrelativePath)方法,可以使用../符号来加载 classpath外部的资源。   
  596. */    
  597. publicclass ClassLoaderUtil {   
  598.   privatestatic Log log=LogFactory.getLog(ClassLoaderUtil.class );   
  599.  /**   
  600.   *Thread.currentThread().getContextClassLoader().getResource("")   
  601.  */    
  602.   
  603.  /**   
  604.   *加载Java类。 使用全限定类名   
  605.   *@paramclassName   
  606.   *@return   
  607.  */    
  608.   publicstatic Class loadClass(String className) {   
  609.    try  {   
  610.     return  getClassLoader().loadClass(className);   
  611.    } catch  (ClassNotFoundException e) {   
  612.     thrownew RuntimeException("class not found '" +className+ "'" , e);   
  613.    }   
  614.  }   
  615.  /**   
  616.   *得到类加载器   
  617.  *@return   
  618.  */    
  619.   publicstatic ClassLoader getClassLoader() {   
  620.   return  ClassLoaderUtil. class .getClassLoader();   
  621.   }   
  622.  /**   
  623.  *提供相对于classpath的资源路径,返回文件的输入流   
  624.  *@paramrelativePath必须传递资源的相对路径。是相对于classpath的路径。如果需要查找 classpath外部的资源,需要使用 ../来查找   
  625.  *@return 文件输入流   
  626.  *@throwsIOException   
  627.  *@throwsMalformedURLException   
  628.  */    
  629.   publicstatic InputStream getStream(String relativePath) throws  MalformedURLException, IOException {   
  630.    if (!relativePath.contains( "../" )){   
  631.    return  getClassLoader().getResourceAsStream(relativePath);   
  632.    }else {   
  633.     return  ClassLoaderUtil.getStreamByExtendResource(relativePath);   
  634.    }   
  635.  }   
  636.  /**   
  637.   *   
  638.  *@paramurl   
  639.  *@return   
  640.  *@throwsIOException   
  641.  */    
  642.   publicstatic InputStream getStream(URL url) throws  IOException{   
  643.    if (url!= null ){   
  644.     return  url.openStream();   
  645.    }else {   
  646.     returnnull;   
  647.   }   
  648.  }   
  649.  /**   
  650.   *   
  651.   *@paramrelativePath必须传递资源的相对路径。是相对于classpath的路径。如果需要查找classpath外部的资源,需要使 用 ../来查找   
  652.  *@return   
  653.  *@throwsMalformedURLException   
  654.  *@throwsIOException   
  655.  */    
  656.   publicstatic InputStream getStreamByExtendResource(String relativePath) throws  MalformedURLException, IOException{   
  657.    return  ClassLoaderUtil.getStream(ClassLoaderUtil.getExtendResource(relativePath));   
  658.   }   
  659.   
  660.  /**   
  661.  *提供相对于classpath的资源路径,返回属性对象,它是一个散列表   
  662.  *@paramresource   
  663.  *@return   
  664.  */    
  665.   publicstatic Properties getProperties(String resource) {   
  666.    Properties properties = new  Properties();   
  667.    try  {   
  668.     properties.load(getStream(resource));   
  669.   } catch  (IOException e) {   
  670.     thrownew RuntimeException("couldn't load properties file '" +resource+ "'" , e);   
  671.    }   
  672.   return  properties;   
  673.   }   
  674.  /**   
  675.  *得到本Class所在的ClassLoader的Classpat的绝对路径。   
  676.  *URL形式的   
  677.  *@return   
  678.  */    
  679.   publicstatic String getAbsolutePathOfClassLoaderClassPath(){   
  680.    ClassLoaderUtil.log.info(ClassLoaderUtil.getClassLoader().getResource("" ).toString());   
  681.    return  ClassLoaderUtil.getClassLoader().getResource( "" ).toString();   
  682.   }   
  683.  /**   
  684.  *   
  685.   *@paramrelativePath 必须传递资源的相对路径。是相对于classpath的路径。如果需要查找classpath外部的资源,需要 使 用../来查找   
  686.  *@return资 源的绝对URL   
  687.   *@throwsMalformedURLException   
  688.  */    
  689.   publicstatic URL getExtendResource(String relativePath) throws  MalformedURLException{   
  690.    ClassLoaderUtil.log.info("传入的相对路径:" +relativePath) ;   
  691.    //ClassLoaderUtil.log.info(Integer.valueOf(relativePath.indexOf("../"))) ;    
  692.    if (!relativePath.contains( "../" )){   
  693.    return  ClassLoaderUtil.getResource(relativePath);   
  694.    }   
  695.    String classPathAbsolutePath=ClassLoaderUtil.getAbsolutePathOfClassLoaderClassPath();   
  696.    if (relativePath.substring( 01 ).equals( "/" )){   
  697.     relativePath=relativePath.substring(1 );   
  698.    }   
  699.    ClassLoaderUtil.log.info(Integer.valueOf(relativePath.lastIndexOf("../" ))) ;   
  700.    String wildcardString=relativePath.substring(0 ,relativePath.lastIndexOf( "../" )+ 3 );   
  701.    relativePath=relativePath.substring(relativePath.lastIndexOf("../" )+ 3 );   
  702.    int  containSum=ClassLoaderUtil.containSum(wildcardString,  "../" );   
  703.    classPathAbsolutePath= ClassLoaderUtil.cutLastString(classPathAbsolutePath, "/" , containSum);   
  704.    String resourceAbsolutePath=classPathAbsolutePath+relativePath;   
  705.    ClassLoaderUtil.log.info("绝对路径:" +resourceAbsolutePath) ;   
  706.    URL resourceAbsoluteURL=new  URL(resourceAbsolutePath);   
  707.    return  resourceAbsoluteURL;   
  708.   }   
  709.  /**   
  710.  *   
  711.   *@paramsource   
  712.   *@paramdest   
  713.   *@return   
  714.  */    
  715.   privatestaticint containSum(String source,String dest){   
  716.    int  containSum= 0 ;   
  717.   int  destLength=dest.length();   
  718.    while (source.contains(dest)){   
  719.     containSum=containSum+1 ;   
  720.     source=source.substring(destLength);   
  721.   }   
  722.    return  containSum;   
  723.   }   
  724.  /**   
  725.  *   
  726.   *@paramsource   
  727.   *@paramdest   
  728.   *@paramnum   
  729.   *@return   
  730.  */    
  731.   privatestatic String cutLastString(String source,String dest,int  num){   
  732.   // String cutSource=null;    
  733.    for ( int  i= 0 ;i<num;i++){   
  734.     source=source.substring(0 , source.lastIndexOf(dest, source.length()- 2 )+ 1 );   
  735.    }   
  736.   return  source;   
  737.   }   
  738.  /**   
  739.  *   
  740.   *@paramresource   
  741.   *@return   
  742.  */    
  743.   publicstatic URL getResource(String resource){   
  744.    ClassLoaderUtil.log.info("传入的相对于classpath的路径:" +resource) ;   
  745.    return  ClassLoaderUtil.getClassLoader().getResource(resource);   
  746.   }   
  747.  /**   
  748.  *@paramargs   
  749.  *@throwsMalformedURLException   
  750.  */    
  751.   publicstaticvoid main(String[] args) throws  MalformedURLException {   
  752.    //ClassLoaderUtil.getExtendResource("../spring/dao.xml");    
  753.    //ClassLoaderUtil.getExtendResource("../../../src/log4j.properties");    
  754.    ClassLoaderUtil.getExtendResource("log4j.properties" );   
  755.    System.out.println(ClassLoaderUtil.getClassLoader().getResource("log4j.properties" ).toString());   
  756.   }   
  757. }   
  758.   
  759.    后记   
  760.   
  761.   ClassLoaderUtil类的public   static  URL getExtendResource(String relativePath), 虽然很简单,但是确实可以解决大问题。   
  762.   
  763.    不过这个方法还是比较简陋的。我还想在未来有空时,进一步增强它的能力。比如,增加Ant风格的匹配符。用**代表多个目录,*代表多个字符,?代表一 个字符。达到Spring那样的能力,一次返回多个资源的URL,进一步方便大家开发。   
  764.   
  765.    总结:   
  766.   
  767.   1 .尽量不要使用相对于System.getProperty( "user.dir" )当前用户目录的相对路径。  
  768.    2 .尽量使用URI形式的绝对路径资源。它可以很容易的转变为 URI,URL,File对象。   
  769.   
  770.    3 .尽量使用相对classpath的相对路径。不要使用绝对路径。使用上面 ClassLoaderUtil类的 public   static  URL getExtendResource(String relativePath) 方法已经能够使用相对于classpath的相对路径定位所有位置的资源。   
  771.   
  772.    4 .绝对不要使用硬编码的绝对路径。因为,我们完全可以使用 ClassLoader类的getResource( "" )方法得 到当前classpath的绝对路径。   
  773. 使用硬编码的绝对路径是完全没有必要的!它一定 会让你死的很难看!程序将无法移植!   
  774.   
  775.   如果你一 定要指定一个绝对路径,那么使用配置文件,也比硬编码要好得多!   
  776.   
  777.    当然,我还是推荐你使用程序得到classpath的绝对路径来拼资源的绝对路径!   
  778.   
  779. 1 .如何获得当前文件路径   
  780. 常 用:   
  781. 字符串类型:System.getProperty("user.dir" );   
  782. 综 合:   
  783. package  com.zcjl.test.base;   
  784. import  java.io.File;   
  785. public   class  Test {   
  786.     public   static   void  main(String[] args)  throws  Exception {   
  787.         System.out.println(   
  788.             Thread.currentThread().getContextClassLoader().getResource("" ));   
  789.         System.out.println(Test.class .getClassLoader().getResource( "" ));   
  790.         System.out.println(ClassLoader.getSystemResource("" ));   
  791.         System.out.println(Test.class .getResource( "" ));   
  792.         System.out.println(Test.class .getResource( "/" ));   
  793.   
  794.         System.out.println(new  File( "" ).getAbsolutePath());   
  795.         System.out.println(System.getProperty("user.dir" ));   
  796.     }   
  797. }   
  798. file:/E:/workSpace/javaTest/target/classes/   
  799. file:/E:/workSpace/javaTest/target/classes/   
  800. file:/E:/workSpace/javaTest/target/classes/   
  801. file:/E:/workSpace/javaTest/target/classes/javaAPI/   
  802. file:/E:/workSpace/javaTest/target/classes/   
  803. E:/workSpace/javaTest   
  804. E:/workSpace/javaTest   
  805.   
  806. 2 .Web服务中   
  807. (1 ).Weblogic   
  808. WebApplication 的系统文件根目录是你的weblogic安装所在根目录。   
  809. 例如:如果你的weblogic安装在 c:/bea/weblogic700.....   
  810. 那么,你的文件根路径就是c:/.   
  811. 所 以,有两种方式能够让你访问你的服务器端的文件:   
  812. a.使用绝对路径:   
  813. 比 如将你的参数文件放在c:/yourconfig/yourconf.properties,   
  814. 直接使 用 new  FileInputStream( "/yourconfig/yourconf.properties" );   
  815. b. 使用相对路径:   
  816. 相对路径的根目录就是你的webapplication的根路径,即WEB-INF的 上一级目录,将你的参数文件放在yourwebapp/yourconfig/yourconf.properties,   
  817. 这 样使用:   
  818. new  FileInputStream( "yourconfig/yourconf.properties" );   
  819. 这 两种方式均可,自己选择。   
  820. (2 ).Tomcat   
  821. 在 类中输出System.getProperty("user.dir" );显示的 是%Tomcat_Home%/bin   
  822. (3 ).Resin   
  823. 不 是你的JSP放的相对路径,是JSP引擎执行这个JSP编译成SERVLET   
  824. 的路径为根.比如用新建 文件法测试File f = new  File( "a.htm" );   
  825. 这个 a.htm在resin的安装目录下   
  826. (4 ). 如何读相对路径哪?   
  827. 在Java文件中getResource或 getResourceAsStream均可   
  828. 例:getClass().getResourceAsStream(filePath);//filePath可以是"/filename",这里的/代表web发布根路径下WEB-INF /classes    
  829. 也可以 getClass().getClassLoader().getResourceAsStream(filePath)//filePath不是带“/”的    
  830. (5 ).获得文件真实路径   
  831. string  file_real_path=request.getRealPath("mypath/filename" );    
  832. 通 常使用request.getRealPath("/" );    
  833. 4 .遗留问题   
  834. 目前new  FileInputStream()只会使用绝对路径,相对   
  835.   
  836.   InputStream in1 = new  FileInputStream( "abc1.properties" );  // 相对路径    
  837.   InputStream in2 = new  FileInputStream( "/abc2.properties" );  // 绝对路径,E盘下    
  838.   InputStream in3 = new  FileInputStream( "e://abc3.properties" ); //相对路径   
  839. 5 .按Java文件类型分类读取配置文件   
  840. 配 置 文件是应用系统中不可缺少的,可以增加程序的灵活性。java.util.Properties是从jdk1.2 就 有的类,一直到现在都支持load ()方法,jdk1. 4 以后 save(output,string) ->store(output,string)。如果只是单纯的读,根本不存在烦恼的问题。web层可以 通过 Thread.currentThread().getContextClassLoader().   
  841. getResourceAsStream("xx.properties" ) 获取;   
  842. Application 可以通过new  FileInputStream( "xx.properties" );直接在classes一级获取。关键是有时我们需要通过 web修改配置文件,我们不 能将路径写死了。经过测试觉得有以下心得:   
  843. 1 .servlet中读写。如果运用Struts 或者Servlet可以直接在初始化参数中 配置,调用时根据servlet的getRealPath( "/" ) 获取真实路径,再根据String file =  this .servlet.getInitParameter( "abc" );获取相对的WEB-INF的相对路径。   
  844. 例:   
  845. InputStream input = Thread.currentThread().getContextClassLoader().   
  846. getResourceAsStream("abc.properties" );   
  847. Properties prop = new  Properties();   
  848. prop.load(input);   
  849. input.close();   
  850. OutputStream out = new  FileOutputStream(path);   
  851. prop.setProperty("abc" , “test");   
  852. prop.store(out, “–test–");   
  853. out.close();   
  854. 2 .直接在jsp中操作,通过jsp内置对象获取可操作的绝对地址。   
  855. 例:   
  856. // jsp页面    
  857. String path = pageContext.getServletContext().getRealPath("/" );   
  858. String realPath = path+"/WEB-INF/classes/abc.properties" ;   
  859. //java 程序    
  860. InputStream in = getClass().getClassLoader().getResourceAsStream("abc.properties" );  // abc.properties放在webroot/WEB-INF/classes/目录下    
  861. prop.load(in);   
  862. in.close();   
  863. OutputStream out = new  FileOutputStream(path);  // path为通过页面传入的路径    
  864. prop.setProperty("abc" , “abcccccc");   
  865. prop.store(out, “–test–");   
  866. out.close();   
  867. 3 .只通过Java程序操作资源文件   
  868. InputStream in = new  FileInputStream( "abc.properties" );  // 相对路径,项目下的路径    
  869. OutputStream out = new  FileOutputStream( "abc.properties" );























一、关于绝对路径和相对路径
1.基本概念的理解绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)例如:C:xyz est.txt代表了test.txt文件的绝对路径。http://www.s.com/inx.htm也代表了一个URL绝对路径。相对路径:相对于 某个基准目录的路径。包含Web的相对路径(HTML中的相对目录),例如:在Servlet中,"/"代表Web应用的跟目录。和物理路径的相对表示。 例如:"./" 代表当前目录,"../"代表上级目录。这种类似的表示,也是属于相对路径。另外关于URI,URL,URN等内容,请参考RFC相关文档标准。RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax,(http://www.ietf.org/rfc/rfc2396.txt)2.关于JSP/Servlet中的相对路径和绝对路径。 2.1服务器端的地址服务器端的相对地址指的是相对于你的web应用的地址,这个地址是在服务器端解析的(不同于html和javascript中的相对 地址,他们是由客户端浏览器解析的)
1、request.getRealPath
方法:request.getRealPath("/")得到的路径:C:/Program Files/Apache Software Foundation/Tomcat 5.5/webapps/strutsTest/
方法:request.getRealPath(".")得到的路径:C:/Program Files/Apache Software Foundation/Tomcat 5.5/webapps/strutsTest/.
方法:request.getRealPath("")得到的路径:C:/Program Files/Apache Software Foundation/Tomcat 5.5/webapps/strutsTest
request.getRealPath("web.xml")C:/Program Files/Apache Software Foundation/Tomcat 5.5/webapps/strutsTest/web.xml
2、request.getParameter("");    ActionForm.getMyFile();
方法:String filepath = request.getParameter("myFile");得到的路径:D:/VSS安装目录/users.txt
方法:String filepath = ActionForm.getMyFile();得到的路径:D:/VSS安装目录/users.txt
--------------------------------------------------strutsTest 为工程名
myFile 在ActionForm中,为private String myFile;在jsp页面中:为<html:file property="myFile"></html:file>
--------------------------------------------------
3、获得系统路径
在Application中: System.getProperty("user.dir")
在Servlet中: ServletContext servletContext = config.getServletContext(); String rootPath = servletContext.getRealPath("/");
在jsp中:application.getRealPath("")
4、其他1
1.可以在servlet的init方法里
String path = getServletContext().getRealPath("/");
这将获取web项目的全路径
例如 :E:/eclipseM9/workspace/tree/
tree是我web项目的根目录
2.你也可以随时在任意的class里调用
this.getClass().getClassLoader().getResource("").getPath();
这将获取到classes目录的全路径
例如 : /D:/workspace/strutsTest/WebRoot/WEB-INF/classes/
还有 this.getClass().getResource("").getPath().toString();
这将获取 到 /D:/workspace/strutsTest/WebRoot/WEB-INF/classes/bl/
这个方法也可以不在web环境里确定路径,比较好用
3.request.getContextPath();
获得web根的上下文环境
如 /tree
tree是我的web项目的root context
5、其他2
java获取路径几种途径-
jdk如何判断程序中的路径呢?一般在编程中,文件路径分为相对路径和绝对路径,绝对路径是比较好处理的,但是不灵活,因此我们在编程中对文件进 行操作的时候,一般都是读取文件的相对路径,相对路径可能会复杂一点,但是也是比较简单的,相对的路径,主要是相对于谁,可以是类加载器的路径,或者是当 前 java文件下的路径,在jsp编程中可能是相对于站点的路径,相对于站点的路径,我们可以通过 getServletContext().getRealPath("/") 和request.getRealPath("/"):这个是取得站点的绝对路径; 而getContextPath():取得站点的虚拟路径;
2:class.getClassLoader.getPath():取得类加载器的路径:什么是类加载器呢?一般类加载器有系统的和用户自己定 义的;系统的ClassLoader就是jdk提供的,他的路径就是jdk下的路径,或者在jsp编程,比如Tomcat ,取得的类加载器的位置就是tomaca自己设计的加载器的路径,明白了这些之后,对于文件路径的操作就会相当的清楚,我们在编程的时候,只要想清楚我们 所操作的文件是相对于什么路径下的,取得相对路径就可以了.
6、总结
1、获取web服务器下的文件路径request.getRealPath("/")application.getRealPath("") 【jsp中 】ServletContext().getRealPath("")
System.getProperty("user.dir")【不同位置调用,获取的路径是动态变化的】
2、获取本地路径
jsp中,<html:file property="myFile"/>
request.getParameter("myFile");ActionForm.getMyFile();获取的值相同:如D:/VSS 安装目录/users.txt
*********************************
this.getClass().getClassLoader().getResource("").getPath();==/D: /workspace/strutsTest/WebRoot/WEB-INF/classes /this.getClass().getResource("").getPath().toString();==/D:/workspace /strutsTest/WebRoot/WEB-INF/classes/bl/
3、获取相对路径
request.getContextPath();
如:/strutsTest

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值