File是用于表示或者说映射实际文件系统对象,如文件或目录。这样java代码就能操作计算机上的文件系统对象了。像setReadOnly()方法等一看就是设置该文件对象为只读。
File类的实例是不可变的;也就是说,一旦创建,File对象表示的抽象路径名将永不改变。
File类内部维护一个FileSystem接口的实现类,这个实现类非常重要,File许多方法的具体操作都是由这个FileSystem实现类完成的。不同操作系统文件系统不一样,那各自的JDK的FileSystem实现类也自然不一样。我用的是Windows系统,它的实现类就是WinNTFileSystem。
File类主要由两个属性path、prefixLength。代表文件对象路径,以及前缀长度(这个前缀长度表示了路径是绝对还是相对的)。新建一个File实例时就是调用FileSystem实现类来操作这两个属性、
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
//将路径标准化(比如规范路径字符串之间的分隔符等)
this.path = fs.normalize(pathname);
//判断前缀长度
this.prefixLength = fs.prefixLength(this.path);
}
想看着个File对象到底对应文件系统哪个对象,可以调用getAbsolutePath()方法查看
public String getAbsolutePath() {
return fs.resolve(this);
}
//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);
String np;
if (dir != null) {
/* When resolving a directory-relative path that refers to a
drive other than the current drive, insist that the caller
have read permission on the result */
String p = drive + (':' + dir + slashify(path.substring(2)));
SecurityManager security = System.getSecurityManager();
try {
if (security != null) security.checkRead(p);
} catch (SecurityException x) {
/* Don't disclose the drive's directory in the exception */
throw new SecurityException("Cannot resolve path " + path);
}
return p;
}
return drive + ":" + slashify(path.substring(2)); /* fake it */
}
throw new InternalError("Unresolvable path: " + path);
}
可以看到当前缀长度为3时,表示生成对象时使用绝对路径(暂称为传递路径),FIle对象对应文件系统对象的路径就是标准化后的传递路径
前缀长度为1时,传递路径为带斜杠的相对路径,那对应文件系统对象的路径就是工作目录(什么是工作目录后面解释)的根目录(即所在盘符位置)+标准化的传递路径
前缀长度为0时,传递路径为不带斜杠的相对路径,对应文件系统对象路径就是标准化后的工作目录+标准化的传递路径
工作目录即System.getProperty('user.dir')的值。这个值就是调用java命令的目录,比如cmd中执行一个class文件,值就是执行命令时所在目录。而在tomcat运行web项目,一般是tomcat目录/bin/startup.bat调用命令,则值就是bin目录。
如果是eclipse 新建的tomcat server ,默认为Working Directory ----- eclipse的目录,可以设置 eclipse下右击tomcat server 点击Open(有可能需要先stop)General Information 下的Open Lauch Configuration的Working directory 设置该路径
idea运行web应用时值默认是配置的tomcat server的bin目录,idea运行java应用时值默认是项目所在目录位置,当然可以通过Edit Configuration中的Working directory来配置