昨天在网上找了一个程序得到类的运行路径,可是如果路径中出现空格,类的路径中就显示%20呢
 程序如下
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;/**
 * @author 由月
 * 
 * 这个类提供了一些根据类的class文件位置来定位的方法。
 */
public class Path {
 /**
  * 获取一个类的class文件所在的绝对路径。 这个类可以是JDK自身的类,也可以是用户自定义的类,或者是第三方开发包里的类。
  * 只要是在本程序中可以被加载的类,都可以定位到它的class文件的绝对路径。
  * 
  * @param cls
  *            一个对象的Class属性
  * @return 这个类的class文件位置的绝对路径。 如果没有这个类的定义,则返回null。
  */
 public static String getPathFromClass(Class cls) throws IOException {
  String path = null;
  if (cls == null) {
   throw new NullPointerException();
  }
  URL url = getClassLocationURL(cls);
  if (url != null) {
   path = url.getPath();
   if ("jar".equalsIgnoreCase(url.getProtocol())) {
    try {
     path = new URL(path).getPath();
    } catch (MalformedURLException e) {
    }
    int location = path.indexOf("!/");
    if (location != -1) {
     path = path.substring(0, location);
    }
   }
   File file = new File(path);
   path = file.getCanonicalPath();
  }
  return path;
 } /**
  * 这个方法可以通过与某个类的class文件的相对路径来获取文件或目录的绝对路径。 通常在程序中很难定位某个相对路径,特别是在B/S应用中。
  * 通过这个方法,我们可以根据我们程序自身的类文件的位置来定位某个相对路径。
  * 比如:某个txt文件相对于程序的Test类文件的路径是../../resource/test.txt,
  * 那么使用本方法Path.getFullPathRelateClass("../../resource/test.txt",Test.class)
  * 得到的结果是txt文件的在系统中的绝对路径。
  * 
  * @param relatedPath
  *            相对路径
  * @param cls
  *            用来定位的类
  * @return 相对路径所对应的绝对路径
  * @throws IOException
  *             因为本方法将查询文件系统,所以可能抛出IO异常
  */
 public static String getFullPathRelateClass(String relatedPath, Class cls)
   throws IOException {
  String path = null;
  if (relatedPath == null) {
   throw new NullPointerException();
  }
  String clsPath = getPathFromClass(cls);
  File clsFile = new File(clsPath);
  String tempPath = clsFile.getParent() + File.separator + relatedPath;
  File file = new File(tempPath);
  path = file.getCanonicalPath();
  return path;
 } /**
  * 获取类的class文件位置的URL。这个方法是本类最基础的方法,供其它方法调用。
  */
 private static URL getClassLocationURL(final Class cls) {
  if (cls == null)
   throw new IllegalArgumentException("null input: cls");
  URL result = null;
  final String clsAsResource = cls.getName().replace('.', '/').concat(
    ".class");
  final ProtectionDomain pd = cls.getProtectionDomain();
  // java.lang.Class contract does not specify
  // if 'pd' can ever be null;
  // it is not the case for Sun's implementations,
  // but guard against null
  // just in case:
  if (pd != null) {
   final CodeSource cs = pd.getCodeSource();
   // 'cs' can be null depending on
   // the classloader behavior:
   if (cs != null)
    result = cs.getLocation();   if (result != null) {
    // Convert a code source location into
    // a full class file location
    // for some common cases:
    if ("file".equals(result.getProtocol())) {
     try {
      if (result.toExternalForm().endsWith(".jar")
        || result.toExternalForm().endsWith(".zip"))
       result = new URL("jar:".concat(
         result.toExternalForm()).concat("!/")
         .concat(clsAsResource));
      else if (new File(result.getFile()).isDirectory())
       result = new URL(result, clsAsResource);
     } catch (MalformedURLException ignore) {
     }
    }
   }
  }  if (result == null) {
   // Try to find 'cls' definition as a resource;
   // this is not
   // document.d to be legal, but Sun's
   // implementations seem to //allow this:
   final ClassLoader clsLoader = cls.getClassLoader();
   result = clsLoader != null ? clsLoader.getResource(clsAsResource)
     : ClassLoader.getSystemResource(clsAsResource);
  }
  return result;
 } public static void main(String[] args) throws Exception
 {
  try {
   System.out.println(getPathFromClass(Path.class));
 //  System.out.println(getFullPathRelateClass("../test/abc/..",  Path.class));
  } catch (Exception e) {
   e.printStackTrace();
  }
 }}
可以直接编译运行的.例如我的运行结果C:/Tomcat/Tomcat%205.5/webapps/axis/WEB-INF/classes
可是真正的路径是
C:/Tomcat/Tomcat 5.5/webapps/axis/WEB-INF/classes注意Tomcat 5.5之间是空格

解决方案 »

  1.   

    试着把url转成uri看看
    其实上面的代码复杂了点。不就是利用
    URL url = ClassLoader.getSystemResource("path with spaces/hello world.properties");
    System.out.println(url);例子中的那个文件“hello world.properties”在类 Test 的所在目录的“path with spaces”子目录中。这里是输出结果: 
    D:\>java -cp . Test 
    file:/D:/path%20with%20spaces/hello%20world.properties 要注意的是,默认的情况下,getSystemResource 搜索的是 Classpath,不是任意的路径。如果要搜索定制的路径,需要定制的 ClassLoader 实现.
    import java.net.*;
    import java.io.*;
     
    public class Test {  
        public static void main(String[] args) throws Exception {
            String path = "path with spaces/hello world.txt";
            URL url = ClassLoader.getSystemResource(path);
            System.out.print("URL: ");
            System.out.println(url); 
            File file = new File(url.toURI());
            if (file.exists()) {
                System.out.println("File found: " + file.toString());
            } else {
                System.out.println("File not found: " + file.toString());
                return;
            }
     
            BufferedReader reader = 
                new BufferedReader(new FileReader(file));
            String s = reader.readLine();
            System.out.println("Message: " + s);
        }

      

  2.   

    url.toURI() 没有这个方法的,上面写错了,直接ClassLoader.getSystemResource(path);
    就可以了。      String path = "path with spaces/hello world.txt";
            try{
                URL url = ClassLoader.getSystemResource(path);
                System.out.print("URL: ");
                System.out.println(url); 
            
            }catch(URISyntaxException e){
            
            }
      

  3.   

    不明白java执行时,相对路径究竟是从哪里开始找的啊
      

  4.   

    网上不少相对路径的文章啊,csdn里就很多。
    你的这个我不清楚,但tomcat是以\webapps\……作为相对目录的。
      

  5.   

    可以用request.getContextPath()来取得上下文路径;如request.getContextPatch()/a/b/c.jsp
      

  6.   

    楼主的测试肯定是错误的,呵呵因为楼主混淆了容器路径和目录路径两个概念,假设IDE为Eclipse(多数人都用这个,嘿嘿)
    源文件路径为src,那么class的路径则为bin(如果取目录路径的话,如楼主的程序)
    如果取容器路径,则其根目录为Web根目录具体的获取方法,等我有空时发布到自己的Blog上去