标题: 键盘录入与File创建 [打印本页] 作者: 秦冲 时间: 2012-5-29 00:23 标题: 键盘录入与File创建 当你使用键盘录入的方式
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
line = bufr.readline();
file = new File(line);
System.out.println(file.getAbsolutePath());
创建一个File对象时,你键盘输入的路径可以为C:\test也可以为C:\\test
也可以为C:\\\\test,我发现只要你的 "\"是成对存在的就行。
而如果你不经过键盘直接创建的话
File f = new File("C:\\test"),就必须加转义了。
原因是否是键盘录入中有过逆向转换? 作者: 闾丘日月 时间: 2012-5-29 01:44
查看File的源代码发现
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
它的构造器调用了文件系统的normalize方法,下面是该方法的声明,它是一个抽象方法
/**
* Convert the given pathname string to normal form. If the string is
* already in normal form then it is simply returned.
*/
public abstract String normalize(String path);
从方法的注释上可以看出他将path做了 转化,转化成一般形式,所以你无论加几个反斜线,甚至你将路径名写成 c:\\//test在windows下一样得到c:\test,但是要注意,当我写成c:\\/\test的时候,他将\t理解成了制表符。。
和你所说的键盘录入和不经过键盘没有任何关系,下面是我的测试代码。
public static void main(String[] args) throws IOException{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = bufr.readLine();
File file = new File(line);
File file1 = new File("c:\\//ts");
System.out.println(file.getAbsolutePath());
System.out.println(file1.getAbsolutePath());
}作者: 闾丘日月 时间: 2012-5-29 07:29
本来想自己将一个输入的文件路径标准化,想了半天没啥头绪。
于是我又很蛋疼的翻阅了Win32FileSystem的源代码。
发现人家为了能够尽量能解析你们这些乱写string的人。那叫一个复杂啊,不多说上代码
/* Normalize the given pathname, whose length is len, starting at the given
offset; everything before this offset is already normal. */
private String normalize(String path, int len, int off) {
if (len == 0) return path;
if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */
int src;
char slash = this.slash;
StringBuffer sb = new StringBuffer(len);
/* Remove redundant slashes from the remainder of the path, forcing all
slashes into the preferred slash */
while (src < len) {
char c = path.charAt(src++);
if (isSlash(c)) {
while ((src < len) && isSlash(path.charAt(src))) src++;
if (src == len) {
/* Check for trailing separator */
int sn = sb.length();
if ((sn == 2) && (sb.charAt(1) == ':')) {
/* "z:\\" */
sb.append(slash);
break;
}
if (sn == 0) {
/* "\\" */
sb.append(slash);
break;
}
if ((sn == 1) && (isSlash(sb.charAt(0)))) {
/* "\\\\" is not collapsed to "\\" because "\\\\" marks
the beginning of a UNC pathname. Even though it is
not, by itself, a valid UNC pathname, we leave it as
is in order to be consistent with the win32 APIs,
which treat this case as an invalid UNC pathname
rather than as an alias for the root directory of
the current drive. */
sb.append(slash);
break;
}
/* Path does not denote a root directory, so do not append
trailing slash */
break;
} else {
sb.append(slash);
}
} else {
sb.append(c);
}
}
String rv = sb.toString();
return rv;
}
这还只解析C:以后的部分,大致意思能搞懂,具体的就懒得看了。可以看到它内部确实给那么些个\\\做了处理
而normalize函数还有个循环调用上面函数的部分。。就是这样,我写成c:\\/\test它还是没处理的那么完美。。所以说我觉得吧楼主不要闲着蛋疼乱输文件路径。。害人哪
public String normalize(String path) {
int n = path.length();
char slash = this.slash;
char altSlash = this.altSlash;
char prev = 0;
for (int i = 0; i < n; i++) {
char c = path.charAt(i);
if (c == altSlash)
return normalize(path, n, (prev == slash) ? i - 1 : i);
if ((c == slash) && (prev == slash) && (i > 1))
return normalize(path, n, i - 1);
if ((c == ':') && (i > 1))
return normalize(path, n, 0);
prev = c;
}
if (prev == slash) return normalize(path, n, n - 1);
return path;
}