« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9694966 建立时间:2004年12月20日 |

| |
[java语言]windows下的java文件路径处理 原创空间, 软件技术, 电脑与网络
邢红瑞 发表于 2007/7/4 17:57:18 |
今天好好讨论一下windows下的java文件路径,其实String path="D:\\a.cmd.txt"是合法的,String path="/D:/a.cmd.txt"和String path="D:\\\\\\\a.cmd.txt"都是合法的, File file=new File(path); System.out.println(file.exists());返回都是true。构建File对象时, public File(String pathname) { if (pathname == null) { throw new NullPointerException(); } this.path = fs.normalize(pathname); this.prefixLength = fs.prefixLength(this.path); }这里fs就是Win32FileSystem类normalize函数/* * Check that the given pathname is normal. If not, invoke the real * normalizer on the part of the pathname that requires normalization. This * way we iterate through the whole pathname string only once. */ public static String normalize(String path) { int n = path.length(); char slash = '\\'; char 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; }这里只是简单的处理,复杂的在这里处理/* * Normalize the given pathname, whose length is len, starting at the given * offset; everything before this offset is already normal. */ private static 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 = '\\'; 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 这里删除n多/ */ 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; }处理前缀/* * A normal Win32 pathname contains no duplicate slashes, except possibly * for a UNC prefix, and does not end with a slash. It may be the empty * string. Normalized Win32 pathnames have the convenient property that the * length of the prefix almost uniquely identifies the type of the path and * whether it is absolute or relative: * * 0 relative to both drive and directory 1 drive-relative (begins with * '\\') 2 absolute UNC (if first char is '\\'), else directory-relative * (has form "z:foo") 3 absolute local pathname (begins with "z:\\") */
private static int normalizePrefix(String path, int len, StringBuffer sb) { int src = 0; while ((src < len) && isSlash(path.charAt(src))) src++; char c; if ((len - src >= 2) && isLetter(c = path.charAt(src)) && path.charAt(src + 1) == ':') { /*由于java诞生于solaris root的根是/ 这里处理掉前面的/ * Remove leading slashes if followed by drive specifier. This hack * is necessary to support file URLs containing drive specifiers * (e.g., "file://c:/path"). As a side effect, "/c:/path" can be * used as an alternative to "c:/path". */ sb.append(c); sb.append(':'); src += 2; } else { src = 0; if ((len >= 2) && isSlash(path.charAt(0)) && isSlash(path.charAt(1))) { /* * UNC pathname: Retain first slash; leave src pointed at second * slash so that further slashes will be collapsed into the * second slash. The result will be a pathname beginning with * "\\\\" followed (most likely) by a host name. */ src = 1; sb.append('\\'); } } return src; }其他的几个函数private static boolean isSlash(char c) { return (c == '\\') || (c == '/'); }
private static boolean isLetter(char c) { return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); }处理后的String path = "/D:\\\\apache-tomcat-5.5.23/webapps/ROOT/WEB-INF\\classes/cmd/4_anti_attack_20070625110640_109.xml"; path = normalize(path); System.out.println(path);就是windows标准的path |
|
|