Spring StringUtils#cleanPath method 浅析

Spring version:  1.2.6.

Function: To erase any './' or '../' in a path.

Note:  Windows separators ("/") are replaced by simple dashes('/').

 /**
  * Normalize the path by suppressing sequences like "path/.." and
  * inner simple dots.
  *

The result is convenient for path comparison. For other uses,
  * notice that Windows separators ("/") are replaced by simple dashes.
  * @param path the original path
  * @return the normalized path
  */
 public static String cleanPath(String path) {
  String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);

  // Strip prefix from path to analyze, to not treat it as part of the
  // first path element. This is necessary to correctly parse paths like
  // "file:core/../core/io/Resource.class", where the ".." should just
  // strip the first "core" directory while keeping the "file:" prefix.

//处理一些文件前缀。如"file:", "jndi:"等等
  int prefixIndex = pathToUse.indexOf(":");
  String prefix = "";
  if (prefixIndex != -1) {
   prefix = pathToUse.substring(0, prefixIndex + 1);
   pathToUse = pathToUse.substring(prefixIndex + 1);
  }

//分解成String token

  String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR);

//用于储存clean 后的path tokens
  List pathElements = new LinkedList();

//用于记录有“../”的个数
  int tops = 0;
  for (int i = pathArray.length - 1; i >= 0; i--) {

//如果是"./"当前目录,则不用处理,注意此处的if...elseif...else,使得第一个if相当于continue效果。
   if (CURRENT_PATH.equals(pathArray[i])) {
    // do nothing
   }
   else if (TOP_PATH.equals(pathArray[i])) {

//记录下“../”已出现的个数
    tops++;
   }
   else {

//如果还有“../”没被“抵消”,那么没向上走一级,则可用于“抵消”一次“../”
    if (tops > 0) {
     tops--;
    }

//如果“../”已经抵消完毕,那么走到此处,只要将token一一存起来即可,注意越高层次的token越应放得考前(其实或者刚好相反),所以每次都插在链表的头部。
    else {
     pathElements.add(0, pathArray[i]);
    }
   }
  }

//生成clean后的新的path

  return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR);
 }

这段代码不宜使用的情况:

1、因为是在循环体内,按照tokens的数量,逐个发现"../"并试图逐个抵消“../”,这可能会存在的一个问题是,tokens不够“抵消”。比如"/a/../../b.xml",需要抵消两次,但最多允许抵消一次(“a/”),但上述循环体内的处理对此无能为力,最终处理成为只剩下b.xml了,这肯定不是想要的结果。但有一点可以肯定的是,如果是绝对路径并且正确,就一定不会存在这个问题;但如果是相对路径,用此就需要格外小心了!或许想方设法将相对路径转为绝对路径不失为上策。

 

你可能感兴趣的:(Open,Source)