获取绝对路径去除路径的%空格问题

本文详细介绍了Java项目中路径问题的解决方案,包括相对路径、类加载目录、Web项目根目录获取、类路径获取等,并提供了多种实用代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class 类

public static String getBasePath(){

String savaPath="";

savaPath= 类.class.getRecource("").getPath();

int i = savaPath.lastIndexOf("WEB-INF");

savaPath= savaPath.substring(1,i);

return savaPath;

}

这个是 转换

String  savePath =  java.net.URLDecoder.decode(savaPath,"utf-8");

java 路径解决方案

Java的路径问题,相对来说就比较繁杂。最近的工作涉及到创建和读取文件的工作,现将实际使用中遇到的问题总结如下: 
一 相对路径的解释 
   1.相对路径(即相对于当前用户目录的相对路径)均可通过以下方式获得(不论是一般的java项目还是web项目)
    String relativelyPath=System.getProperty("user.dir"); 
   对于一般的java项目中的文件是相对于项目的根目录,而对于web项目中的文件路径,可能是 服务器的某个路径,同时不同的web 服务器也不同(tomcat是相对于 tomcat安装目录\bin)。为此,个人认为,在web项目中,最好不要使用“相对于当前用户目录的相对路径”。然而默认情况下,java.io 包中的类总是根据当前用户目录来分析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。这就是说,在使用java.io包中的类时,最好不要使用相对路径。否则,虽然在SE程序中可能还算正常,但是到了EE程序中,弄不好,就会带来问题一片哦。 
   2.相对于classpath的相对路径 
   如:相对于file:/D:/mywork/javaprj/MyTest/bin这个路径的相对路径。其中,bin是本项目的classpath。所有的Java源文件编译后的.class文件复制到这个目录中。

  

  二 类加载目录(即当运行某一类时获得其装载目录) 
   1.不论是一般的java项目还是web项目,先定位到能看到包路径的第一级目录    
        InputStream is=ReadWrite.class.getClassLoader().getResourceAsStream("DeviceNO"); 
    其中,DeviceNO文件的路径为 项目名\src\DeviceNO;类ReadWrite所在包的第一级目录位于src目录下。 
    2.与1相似,不同的是此方法必须以'/'开头       
    InputStream is=ReadWrite.class.getResourceAsStream("DeviceNO"); 
    其中,DeviceNO文件的路径为 项目名\src\DeviceNO;类ReadWrite所在包的第一级目录位于src目录下。 
      
三. web项目根目录获取 
    1. 可建立一个servlet,在其init方法中写入如下语句 
      ServletContext sc=this.getServletContext(); 
     String temp=sc.getRealPath("/"); 
     得到的输出路径结果类似:"D:\Apache\Tomcat6.0\webapps\windpower\ " (windpower为项目名字) ,如果是调用了s1.getRealPath("")则输出"D:\Apache\Tomcat6.0\webapps\windpower"(注意,在最后少了一个"\") 
     2. 在httpServletRequest中,可以通过下面语句 
             String cp=request.getSession().getServletContext().getRealPath("/"); 得到的输出路径结果类似:"D:\Apache\Tomcat6.0\webapps\windpower\ " 
四 .类路径( classpath)的获取(在Eclipse/MyEclipse中,则为获得src或者classes目录的路径) 
    方法1.  Thread.currentThread().getContextClassLoader().getResource("").getPath() 
     例如: 
     String path=Thread.currentThread().getContextClassLoader().getResource("").getPath(); 
     System.out.println(path); 
     打印:“/D:/windpower/WebRoot/WEB-INF/classes/”

      方法2.   ParsingXML.class.getClassLoader().getResource("").getPath()(ParsingXML为src某一个包中的类,下同)

       例如: 
      String path=ParsingXML.class.getClassLoader().getResource("").getPath(); 
     System.out.println("ParsingXML.class.getClassLoader().getResource--"+path); 
     打印: “ParsingXML.class.getClassLoader().getResource--/D:/windpower/WebRoot/WEB-INF/classes/”
    另外,如果想把文件放在某一包中,则可以通过以下方式获得到文件所在目录,即先定位到该包的最后一级目录。 
     ParsingXML.class.getResource("").getPath(); 
     例如: 
      String path=ParsingXML.class.getResource("").getPath(); 
     System.out.println("ParsingXML.class.getResource---"+p2); 
     打印: “ParsingXML.class.getResource---/D:/windpower/WebRoot/WEB-INF/classes/parsing/ ”(ParsingXML为src目录下parsing包中的类) 
五. 属性文件的读取: 
     方法1. 
      static { 
ps = new Properties(); 
try { 
InputStream in = ReadWrite.class.getResourceAsStream("DeviceNO"); 
ps.load(in); 
in.close(); 
} catch (Exception e) { 
e.printStackTrace(); 

          ps.getProperty("key") 
    方法2. 
        Locale locale = Locale.getDefault();  
       ResourceBundle localResource = ResourceBundle.getBundle("windpower/DeviceNOProperties", locale);  
       String value = localResource.getString("1");  
       System.out.println("DeviceNO: " + value); 
       工程src目录下文件DeviceNOProperties.properties(名字后缀必须为properties)文件内容如下:1=3输出结果为:“DeviceNO:3” 
六.编码转换问题: 
    ClassLoader的getResource方法使用了utf-8对路径信息进行了编码,当路径中存在中文和空格时,他会对这些字符进行转换,这样,得到的往往不是我们想要的真实路径,在此,调用了URLDecoder的decode方法进行解码,以便得到原始的中文及空格路径 
例如:结果是file:/C:/Documents%20and%20Settings/%e5%ba%84%e6%99%93%e6%af%85   
  /Local%20Settings/Temp/temp0.jar!/db/dmozdata.mdb   
  而我们期望是 C:/Documents 路径p source  等等。这里我们只要在获取到路径之前把返回值decode下就可以了. 用utf-8编码. Java代码 : 
    String configPath = this.getClass().getClassLoader().getResource("allowPath.xml").getFile(); 
    configPath = java.net.URLDecoder.decode(configPath,"utf-8"); 
    
    另外java中URL 的编码和解码函数java.net.URLEncoder.encode(String s)和java.net.URLDecoder.decode(String s);在javascript 中URL 的编码和解码函数escape(String s)和unescape(String s) ;   
七.总结: 
     我们在使用相对路径时,应当使用相对于当前classpath的相对路径。 
ClassLoader类的getResource(String name),getResourceAsStream(String name)等方法,使用相对于当前项目的classpath的相对路径来查找资源。 
读取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此。 
通过查看ClassLoader类及其相关类的源代码,发现它实际上还是使用了URL形式的绝对路径。通过得到当前classpath的URL形式的绝对路径,再去构建相对路径的URL形式的绝对路径。


在這裡感謝原創的作者,這邊文章真的很好,幫了我大忙了。


<think>我们正在处理一个Java Web项目,需要获取资源文件夹(通常是src/main/resources或类似位置)的绝对路径。 在Web项目中,资源文件在部署后通常位于WEB-INF/classes目录下(因为Maven等构建工具会将资源文件复制到classes目录)。 因此,我们的目标是获取WEB-INF/classes目录的绝对路径,这也就是资源文件夹在部署后的位置。 根据提供的引用,我们可以采用以下几种方法: 方法1:通过类加载器获取 String path = Thread.currentThread().getContextClassLoader().getResource("").getPath(); 这样得到的路径就是WEB-INF/classes目录的绝对路径(URL编码形式,可能需要处理空格等特殊字符)。 方法2:通过任意一个类的getResource方法 String path = YourClass.class.getResource("/").getPath(); 注意:使用"/"表示从类路径的根目录获取。 但是,需要注意的是,这些方法返回的路径可能包含一些特殊字符(如空格会被转义为%20)以及开头的斜杠(在Windows下可能以斜杠开头导致路径问题),因此我们需要进行适当的处理。 另外,在引用[2]中,我们看到一个方法,它同时考虑了Windows和Linux系统,并且去除路径中的WEB-INF/classes部分,但实际上我们不需要去除,因为我们要的正是这个目录。 然而,用户的问题是要获取“资源文件夹”的绝对路径,在部署后,资源文件夹就是WEB-INF/classes。所以我们可以直接使用上述方法。 但是,我们还要注意:在开发环境中(比如在IDE中运行),我们可能希望获取的是项目中的资源文件夹(如src/main/resources)?实际上,在运行期间,资源已经被复制到classes目录,所以我们应该使用类加载器来加载资源,而不是直接访问源码目录。因此,获取到的路径应该是编译后资源所在的路径,即classes目录。 如果用户需要的是源码中的资源目录,这在运行环境中是不可行的,因为部署后只有编译后的资源。所以,我们通常只关心运行时的资源路径。 因此,我们提供以下代码示例: 示例1:使用类加载器 String resourcePath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); // 注意:这里返回的路径可能包含URL编码,比如空格被转义为%20,我们可以使用URLDecoder解码 try { resourcePath = URLDecoder.decode(resourcePath, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } 示例2:使用类的getResource方法 String resourcePath = YourClass.class.getResource("/").getPath(); try { resourcePath = URLDecoder.decode(resourcePath, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } 但是,在Windows系统中,路径可能以斜杠开头,例如:/C:/path/to/project。我们可以根据操作系统进行判断,去掉开头的斜杠(如果存在且是Windows系统)。 引用[4]中展示了一个路径示例:file:/E:/java_web/workspace/...,但我们使用getResource方法返回的路径通常不包含"file:",而是以"/"开头(在Windows下)或者直接是路径(在Linux下)。实际上,getResource返回的URL格式,所以我们可以使用toURI()和File来获取更规范的路径。 更好的做法是使用: URL url = Thread.currentThread().getContextClassLoader().getResource(""); File resourceDir = new File(url.toURI()); 这样我们就可以得到一个File对象,然后通过File对象的getAbsolutePath()方法获取绝对路径。 但是,注意:如果路径中包含特殊字符(比如空格)和URL编码,使用toURI()可以正确转换。但是,如果资源在jar包中,这种方法可能会失败。不过,在Web项目中,资源在WEB-INF/classes目录下,通常不是jar包,所以可以使用。 因此,我们推荐使用以下方法: 方法(使用URI): try { URL url = Thread.currentThread().getContextClassLoader().getResource(""); File resourceDir = new File(url.toURI()); String absolutePath = resourceDir.getAbsolutePath(); System.out.println("资源文件夹绝对路径: " + absolutePath); } catch (URISyntaxException e) { e.printStackTrace(); } 但是,需要注意的是,如果资源路径中包含空格,使用getPath()然后解码可能会遇到问题,而使用toURI()可以避免这个问题。 然而,在Web应用中,如果资源在jar包中,getResource可能会返回jar:file:...这样的URL,此时使用toURI()再创建File会失败(因为jar内的路径不是文件系统路径)。因此,我们需要判断是否在jar中。不过,对于资源文件夹(WEB-INF/classes)来说,它通常是一个目录,所以可以这样用。 另一种更安全的方式是:我们只关心资源文件夹的路径,而且我们知道资源文件夹在Web应用中是一个目录,所以我们可以假设它不是一个jar。因此,我们可以使用上述方法。 但是,如果我们想避免使用URI,也可以使用以下方式(处理空格问题): String path = Thread.currentThread().getContextClassLoader().getResource("").getPath(); String decodedPath = URLDecoder.decode(path, "UTF-8"); // 在Windows下去掉开头的斜杠 if (decodedPath.startsWith("/") && System.getProperty("os.name").toLowerCase().contains("win")) { decodedPath = decodedPath.substring(1); } 但是,这种方式需要处理操作系统差异,不如使用URI方法简洁。 因此,我们推荐使用URI方法,同时注意捕获异常。 总结代码: 在Java Web项目中获取资源文件夹(即类路径根目录)的绝对路径: import java.io.File; import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; public class ResourcePathExample { public static void main(String[] args) { // 获取类加载器 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL url = classLoader.getResource(""); if (url != null) { try { // 方法1:使用toURI(),注意在路径是目录时使用 File resourceDir = new File(url.toURI()); System.out.println("资源文件夹绝对路径 (方法1): " + resourceDir.getAbsolutePath()); } catch (URISyntaxException e) { e.printStackTrace(); } // 方法2:使用getPath()并解码 String path = url.getPath(); try { String decodedPath = URLDecoder.decode(path, "UTF-8"); // 处理Windows路径开头的斜杠 if (decodedPath.startsWith("/") && System.getProperty("os.name").toLowerCase().contains("win")) { decodedPath = decodedPath.substring(1); } System.out.println("资源文件夹绝对路径 (方法2): " + decodedPath); } catch (Exception e) { e.printStackTrace(); } } } } 注意:在Web项目中,我们通常是在服务器环境中运行,所以使用类加载器获取路径是服务器上的部署路径。 另外,如果资源文件夹中有子文件夹,我们可以通过类加载器的getResource("子文件夹名")来获取。 但是,用户问题只是获取资源文件夹的绝对路径,所以我们使用根目录即可。 根据引用[3]和[4],我们还可以通过其他方式获取,但以上方法是最常用的。 最后,我们根据用户的问题,提供最直接的方法: try { URL url = getClass().getClassLoader().getResource(""); File resourceDir = new File(url.toURI()); String absolutePath = resourceDir.getAbsolutePath(); // 使用这个路径 } catch (URISyntaxException e) { // 异常处理 } 或者,如果是在非文件系统(如jar)中,我们不应该使用File,但鉴于Web应用资源目录在文件系统中,所以可以这样用。 如果用户需要获取的是Web应用根目录(例如包含WEB-INF的目录),那么可以使用ServletContext的getRealPath方法,但这里用户明确要资源文件夹(即类路径),所以使用类加载器更合适。 因此,我们回答: 在Java Web项目中,资源文件夹(src/main/resources)在部署后位于WEB-INF/classes目录下。我们可以通过类加载器获取该目录的绝对路径,代码如下: try { // 使用当前类的类加载器获取资源根目录(即classes目录)的URL URL url = getClass().getClassLoader().getResource(""); // 或者使用:URL url = Thread.currentThread().getContextClassLoader().getResource(""); if (url != null) { File resourceDir = new File(url.toURI()); String absolutePath = resourceDir.getAbsolutePath(); // 现在absolutePath就是资源文件夹的绝对路径 } } catch (URISyntaxException e) { // 处理异常 e.printStackTrace(); } 注意:如果资源文件在jar包中,此方法会抛出异常(因为无法将jar内部的URL转换为URI再创建File对象)。但在Web应用中,资源通常位于WEB-INF/classes目录下,所以不会在jar包内,因此可以安全使用。 另外,如果资源文件夹中没有任何文件,getResource("")可能返回null,但这种情况很少见,因为至少会有目录结构。 如果用户希望避免使用URI,也可以使用以下代码: String path = getClass().getClassLoader().getResource("").getPath(); // 解码路径(处理空格等特殊字符) try { path = URLDecoder.decode(path, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // 在Windows系统下,路径可能以斜杠开头,需要去掉 if (path.startsWith("/") && System.getProperty("os.name").toLowerCase().contains("win")) { path = path.substring(1); } 但是,这种方法在Linux下是正常的(以斜杠开头),所以我们需要根据操作系统处理。 因此,我们更推荐使用URI方法,因为它更规范地处理了URL到文件路径的转换。 最后,请根据实际运行环境测试。</think>在 Java Web 项目中获取资源文件夹(如 `src/main/resources`)的绝对路径,需根据部署环境和运行方式选择合适的方法。以下是几种常用方案: ### 方法 1:通过类加载器获取(推荐) ```java import java.net.URL; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; public class ResourcePathUtils { public static String getResourcePath() { try { // 获取资源文件夹根目录的 URL URL url = ResourcePathUtils.class.getClassLoader().getResource(""); if (url == null) { throw new RuntimeException("资源路径未找到"); } // 解码路径(处理空格等特殊字符) String decodedPath = URLDecoder.decode(url.getPath(), StandardCharsets.UTF_8); // 处理 Windows 路径开头的斜杠 if (System.getProperty("os.name").toLowerCase().contains("win") && decodedPath.startsWith("/")) { decodedPath = decodedPath.substring(1); } return decodedPath; } catch (Exception e) { throw new RuntimeException("获取资源路径失败", e); } } } ``` **说明**: - 部署后资源文件位于 `WEB-INF/classes` 目录下,此方法直接获取路径 - 兼容 Windows/Linux,自动处理路径分隔符和 URL 编码 - 示例输出:`/opt/tomcat/webapps/your-project/WEB-INF/classes/`(Linux)或 `C:/tomcat/webapps/your-project/WEB-INF/classes/`(Windows) ### 方法 2:通过 ServletContext 获取(需 Web 环境) ```java import javax.servlet.ServletContext; public class WebResourcePath { public static String getResourcePath(ServletContext context) { // 直接获取 WEB-INF/classes 的物理路径 return context.getRealPath("/WEB-INF/classes"); } } ``` **说明**: - 需在 Servlet 或 Controller 中调用(依赖 `ServletContext`) - 返回示例:`C:\apache-tomcat-9.0\webapps\ROOT\WEB-INF\classes` ### 方法 3:动态解析资源子路径 ```java public class SubResourcePath { public static String getFilePath(String relativePath) { // 获取具体资源文件的 URL URL url = SubResourcePath.class.getResource("/" + relativePath); if (url == null) { throw new RuntimeException("文件未找到: " + relativePath); } return url.getPath().replaceFirst("^/(.:/)", "$1"); // 修复 Windows 盘符路径 } } ``` **调用示例**: ```java String configPath = getFilePath("config/app.properties"); // 输出示例:/opt/tomcat/webapps/ROOT/WEB-INF/classes/config/app.properties ``` --- ### 关键注意事项 1. **部署位置差异**: - IDE 中运行时:路径指向项目 `target/classes` - Tomcat 部署后:路径指向 `WEB-INF/classes` - 路径示例: $$ \text{Tomcat 路径} + \text{/WEB-INF/classes} $$ 2. **特殊字符处理**: - 使用 `URLDecoder.decode()` 解决路径中 `%20` 等编码问题 - 路径中的空格需显式处理: $$ \text{file:/path/with%20space} \rightarrow \text{/path/with space} $$ 3. **跨平台兼容**: - Windows 路径需移除开头的 `/`(如 `/C:/path` → `C:/path`) - 使用 `File.separator` 或 `Paths.get()` 处理路径拼接 4. **资源加载方式**: - 优先用 `ClassLoader.getResourceAsStream()` 直接读取文件流 - 避免硬编码路径,保持环境无关性 > **提示**:生产环境推荐优先使用类加载器直接读取资源流(`getResourceAsStream`),而非获取物理路径,避免路径依赖问题[^1][^2][^3]。 --- ### 相关问题 1. 如何在 Spring Boot 中获取 `resources` 目录路径? 2. Java 读取资源文件时出现 `NullPointerException` 的可能原因? 3. 如何解决 Tomcat 部署后资源文件找不到的问题? 4. 在单元测试中如何模拟 Web 环境获取资源路径? 5. 为什么 `getResource()` 返回的路径包含 `file:` 或 `jar:` 前缀?如何解析? [^1]: 通过类加载器获取资源路径是标准做法,兼容 IDE 和服务器环境 [^2]: 处理 Windows/Linux 路径差异需检查 `File.separator` 和系统属性 [^3]: `URLDecoder` 解决空格等特殊字符问题,避免路径解析失败 [^4]: 直接操作文件路径时应考虑服务器权限和路径安全性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值