A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 秦冲 黑马帝   /  2012-5-29 00:23  /  2176 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

当你使用键盘录入的方式
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"),就必须加转义了。
原因是否是键盘录入中有过逆向转换?

评分

参与人数 1技术分 +1 收起 理由
攻城狮 + 1 赞一个!

查看全部评分

2 个回复

倒序浏览
查看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());
        }

评分

参与人数 1技术分 +1 收起 理由
攻城狮 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本来想自己将一个输入的文件路径标准化,想了半天没啥头绪。
于是我又很蛋疼的翻阅了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);

        if (off == 0) {
            /* Complete normalization, including prefix */
            src = normalizePrefix(path, len, sb);
        } else {
            /* Partial normalization */
            src = off;
            sb.append(path.substring(0, off));
        }

        /* 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;
    }
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马