java.io.File.separator 文件分隔符
win10上是\
list()和getParent()
前者返回子内容
后者返回父目录
list()和listFiles()
两者都是返回目录的内容(文件或目录),
前者返回 String[]
后者返回 File[]
前者只是内容的基本名称
后者 是内容的全名
以F:\Temp为例,其目录内容如下
list()返回
listFiles()返回
getCanonicalFile
返回绝对路径,且没有.和..等表示当前/上一级的字符
File f = new File("program.txt");
File canonical = f.getCanonicalFile(); //返回 C:\Users\pc\eclipse-workspace1\arnab\program.txt
File f = new File("c:\\users\\..\\program");
File canonical = f.getCanonicalFile(); //返回C:\program
createNewFile() 和 mkdir()
前者创建文件,(而不是目录)
而mkdir()创建目录 而不是文件
两者的共同点都是 父目录必须存在
比如无论创建F:\Temp\mkdir3\mkdir2\mkdir1\mkdir目录还是文件
父目录F:\Temp\mkdir3\mkdir2\mkdir1\必须已经存在
若想创建一个父目录不存在的文件,操作如下
file.getParentFile().mkdirs(); //创建父目录,如果父目录已存在,不会报错,仅返回false
file.createNewFile() //创建自身新文件
若想创建一个父目录不存在的目录,操作如下
file.mkdirs() //递归创建目录
getParent()和getParentFile()
前者返回父目录字符串, 后者进一步将其转化为File对象
mkdirs()
创建目录的,可以创建多级目录, 比如D:\filepath\test\test.txt 将创建一系列目录,test.txt是最后一个目录
内部调用了mkdir()
代码如下, 会递归创建父目录,最终导致从根目录开始一级一级往下创建,直到最后一级
public boolean mkdirs() {
if (exists()) {
return false;
}
if (mkdir()) {
return true;
}
File canonFile = null;
try {
canonFile = getCanonicalFile();
} catch (IOException e) {
return false;
}
File parent = canonFile.getParentFile();
return (parent != null && (parent.mkdirs() || parent.exists()) && //先创建父目录,或者已存在
canonFile.mkdir()); //再创建自身目录
}
getName() 和 getParent() 和 getPath()
getParent() + getName() 可以认为是 全路径即 getPath()
getName()返回文件/目录的基本名
getParent()返回父目录
如F:\Temp\mkdir3\mkdir2\..\..\mkdir 返回mkdir
File对象的prefixLength字段貌似指的是文件所在盘符,比如这里的F:\ 长度为3
下面是两者的源代码,
其中index是最后一个分隔符索引
可以看到两者的处理是相反的,前者返回后缀子串(基本名), 后者返回前缀子串(父目录)
public String getName() {
int index = path.lastIndexOf(separatorChar);
if (index < prefixLength) return path.substring(prefixLength);
return path.substring(index + 1);
}
public String getParent() {
int index = path.lastIndexOf(separatorChar);
if (index < prefixLength) {
if ((prefixLength > 0) && (path.length() > prefixLength))
return path.substring(0, prefixLength);
return null;
}
return path.substring(0, index);
}
isInvalid()
/**
* Check if the file has an invalid path. Currently, the inspection of
* a file path is very limited, and it only covers Nul character check.
* Returning true means the path is definitely invalid/garbage. But 返回true表示无效
* returning false does not guarantee that the path is valid. 返回false不保证有效, 即可能有效
*
* @return true if the file path is invalid.
*/
final boolean isInvalid() {
if (status == null) {
status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED //path里不包含\u0000则有效
: PathStatus.INVALID; //包含则一定无效
}
return status == PathStatus.INVALID;
}
fs.resolve() 和 getCanonicalPath() & getAbsolutePath()
fs.resolve(this) 获取文件路径的绝对形式,即绝对路径
被getAbsolutePath and getCanonicalPath 调用
//比getAbsolutePath()多了一步canonicalize()
public String getCanonicalPath() throws IOException {
if (isInvalid()) {
throw new IOException("Invalid file path");
}
return fs.canonicalize(fs.resolve(this));
}
//
public String getAbsolutePath() {
return fs.resolve(this);
}