Java在Windows下的绝对路径, 完全相对路径 和 目录相对路径等路

额, 不得不说, 论坛是个好地方, 每隔几天总有很好的问题出现. 这篇博客还是因为一个有意思的帖子. 这次的问题和路径的表示方法有关. 帖子在这里: 《求java大神,关于se中的文件操作》

注: “完全相对路径”和”目录相对路径” 的英文分别为 “Completely relative”, “Directory-relative”, 限于本人英文水平, 翻译的可能有些问题, 还请大家指导

原问题

帖子地址: 问题的大致意思是说: 当使用File(String pathname)去构造一个File对象是, 参数”e:”和”e:\\”有什么区别? 估计大多数人和我最开始的想法一样: 没区别. 然后下面就有位仁兄截了个图, 证明这两个是有区别的. 本着实事求是的精神, 我也测了测, 发现当java程序的当前路径在e盘时, “e:”和”e:\\”还真不一样…

源程序

为了方便说明问题, 这里的源程序跟帖子上稍微有点区别.

import java.io.*;class Test{(String[] args){digui(new File(“e:”));digui(new File(“e:\\”));}(File f){System.out.println(f.getPath());if( !f.exists() ){System.out.println(“not exist”);return;}File [] name = f.listFiles();System.out.println(name.length);for(int i = 0 ;i < name.length; i++){System.out.println(name[i]);}}}

将这个程序中的 “e:”和”e:\\”改成自己的工作盘符, 运行程序, 就会发现这两个路径的区别…

API文档上有关的说明

为了解释这个现象, 我首先查看了File类的文档, 看看有没有什么特殊说明. 只是发现了这样一句话

对于 Microsoft Windows 平台,包含盘符的路径名前缀由驱动器号和一个 “:” 组成。如果路径名是绝对路径名,,还可能后跟 “\\”。

注意, 上面说如果是绝对路径名, 还可能跟”\\”. 也就是说, 即使是以 驱动器号+”:” 开始的路径, 也不一定是绝对路径! 同时,经过测试, getPath方法得到的并不是完整的路径!仅仅是把我们传进去的参数标准化了而已. 我们在API中发现两个可以替代的方法: getAbsolutePath方法, 以及getCanonicalPath方法. 这里我们只使用getAbsolutePath方法

public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串。 (以下省略n行)…

更详细的信息, 请查看JDK API文档. 然后我们修改一下我们的程序.将

System.out.println(f.getPath());

修改为

System.out.println(“path:[” + f.getPath() + “] absolutePath:[” + f.getAbsolutePath() + “]”);

从API文档只能得到这么多信息了, 为了的到更加详细的信息, 接下来, 我们看看Java类库的源码.(我的是jdk 1.8.0_45附带的源码)

从Java类库源码得到的信息

从输出来看, getAbsolutePath方法输出的就是File对象所表示的路径, 那么就让我们先看看File类的构造方法, 然后再看看getAbsolutePath方法. 可能就会得到我们想要的信息.

File类的构造方法

首先, 我们看看File(String pathname)方法的源码:

public File(String pathname) {if (pathname == null) {throw new NullPointerException();}this.path = fs.normalize(pathname);this.prefixLength = fs.prefixLength(this.path);}

这里的normalize(pathname)是标准化路径. 我们就不继续向下查看的. 对于我们讨论的这两种路径表示方法, 返回值都是原本的值.

getAbsolutePath方法

由于getAbsolutePath里需要使用到prefixLength属性. 同时在Windows下, 实现FileSystem接口的类是:WinNTFileSystem类. 所以, 我们看看WinNTFileSystem.prefixLength(path)方法: java.io.WinNTFileSystem.java

(String path) {char slash = this.slash;int n = path.length();if (n == 0) return 0;char c0 = path.charAt(0);char c1 = (n > 1) ? path.charAt(1) : 0;if (c0 == slash) {;/* Drive-relative “\\foo” */}if (isLetter(c0) && (c1 == ‘:’)) {if ((n > 2) && (path.charAt(2) == slash));/* Directory-relative “z:foo” */}return 0;/* Completely relative */}

从上面的代码来看

“e:\\”对应的File对象的prefixLength属性为3″e:”对应的File对象的prefixLength属性为2FileSystem.resolve方法

由于File.getAbsolutePath方法直接调用了FileSystem.resolve. 所以,我们查看一下WinNTFileSystem.resolve方法:

public String resolve(File f) {String path = f.getPath();int pl = f.getPrefixLength();if ((pl == 2) && (path.charAt(0) == slash))return path;/* UNC */if (pl == 3)return path;/* Absolute local */if (pl == 0)return getUserPath() + slashify(path); /* Completely relative */if (pl == 1) {/* Drive-relative */String up = getUserPath();String ud = getDrive(up);if (ud != null) return ud + path;return up + path;/* User dir is a UNC path */}if (pl == 2) {/* Directory-relative */String up = getUserPath();String ud = getDrive(up);if ((ud != null) && path.startsWith(ud))return up + slashify(path.substring(2));char drive = path.charAt(0);String dir = getDriveDirectory(drive);…return drive + “:” + slashify(path.substring(2)); /* fake it */}throw new InternalError(“Unresolvable path: ” + path);}private String slashify(String p) {if ((p.length() > 0) && (p.charAt(0) != slash)) return slash + p;else return p;}getUserPath方法返回System.getProperty(“user.dir”), 也就是当前的工作目录.getDrive返回路径的盘符部分

那么

“e:\\”构造的File对象的getAbsolutePath方法返回”e:\\”. “e:”构造的File对象的getAbsolutePath方法返回该应用程序在e盘下的工作目录

那么, e盘下的工作目录是什么? 相信大家都在cmd里执行过这几条命令:

C:\Windows\System32>cd e:\win8 C:\Windows\System32>e: E:\win8>c: C:\Windows\System32>

这里, E:\\win8就是E盘的工作路径. C:\\Windows\\System32就是C盘的工作路径. 而目录相对路径就是相对于这些目录. 比如:

C:drivers 就是 C:\\Windows\\System32\\drivers E:eclipse 就是 E:\\win8\\eclipse

但是由于我们没有切换到F盘过, 工作路径也不是F盘, 所以

F:就是F:\\ F:test 就是 F:\\test

每当我看天的时候我就不喜欢再说话,每当我说话的时候我却敢看天。

Java在Windows下的绝对路径, 完全相对路径 和 目录相对路径等路

相关文章:

你感兴趣的文章:

标签云: