热门文章 | 热门软件| 热门源码 | 热门电影 | 知识库 | 联系我们
软件 源码 教程 影视 健康 招聘
  HTML | JavaScript | ASP | PHP | JSP | NET | VB | VC | VF | Windows | Linux | Mysql | Mssql | Oracle | Struts 
当前位置: 创世纪计算机资源网 -> 文章频道 ->java 
站内搜索:
windows下的java文件路径处理
作者:邢红瑞 来源:blog 整理日期:2007-7-7

今天好好讨论一下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

相关文章