java File源碼理解,探索File路徑

1.方法: new File(path);java

咱們知道根據輸入的路徑path的不一樣 ,File能夠根據path的不一樣格式,來訪問文件。那麼,path的形式有幾種呢?c++

根據源碼windows

 

 

能夠知道,輸入的路徑path實際上是在類FileSystem中處理的。FileSystem是一個抽象類,因此,實際上是在其實現類WinNTFileSystem中處理。app

 

設定一個目標,咱們要獲得文件的絕對地址!ide

由以下代碼post

能夠看出,咱們是從WinNTFileSystem 的resolve獲得絕對路徑this

    @Override
    public String resolve(File f) {
        String path = f.getPath();
        int pl = f.getPrefixLength();
        if ((pl == 2) && (path.charAt(0) == slash))
            return path;                        /* UNC */
        if (pl == 3)
            return path;                        /* Absolute local */
        if (pl == 0)
            return getUserPath() + slashify(path); /* Completely relative */
        if (pl == 1) {                          /* Drive-relative */
            String up = getUserPath();
            String ud = getDrive(up);
            if (ud != null) return ud + path;
            return up + path;                   /* User dir is a UNC path */
        }
        if (pl == 2) {                          /* Directory-relative */
            String up = getUserPath();
            String ud = getDrive(up);
            if ((ud != null) && path.startsWith(ud))
                return up + slashify(path.substring(2));
            char drive = path.charAt(0);
            String dir = getDriveDirectory(drive);
            String np;
            if (dir != null) {
                /* When resolving a directory-relative path that refers to a
                   drive other than the current drive, insist that the caller
                   have read permission on the result */
                String p = drive + (':' + dir + slashify(path.substring(2)));
                SecurityManager security = System.getSecurityManager();
                try {
                    if (security != null) security.checkRead(p);
                } catch (SecurityException x) {
                    /* Don't disclose the drive's directory in the exception */
                    throw new SecurityException("Cannot resolve path " + path);
                }
                return p;
            }
            return drive + ":" + slashify(path.substring(2)); /* fake it */
        }
        throw new InternalError("Unresolvable path: " + path);
    }

咱們須要兩個參數,即String path = f.getPath();和int pl = f.getPrefixLength();spa

 獲得pathcode

注意:windows 把"\\"當成"\"處理,即 "\\".length() ==1orm

  @Override
    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)  // 1:包含「/」
                return normalize(path, n, (prev == slash) ? i - 1 : i);
            if ((c == slash) && (prev == slash) && (i > 1)) /:2:包含  "\",而且"\\",而且i>1
                return normalize(path, n, i - 1);
            if ((c == ':') && (i > 1))   //3:包含 ":",而且i>1
                return normalize(path, n, 0);
            prev = c;
        }
        if (prev == slash) return normalize(path, n, n - 1);
        return path;  //4:如果絕對路徑,則直接返回絕對路徑
//5:"\\" 或 "\" 開頭,直接返回 }
    /* 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;
    }

路徑類型的分類:

    @Override
    public int prefixLength(String path) {
        char slash = this.slash;
        int n = path.length();
        if (n == 0) return 0;
        char c0 = path.charAt(0);
        char c1 = (n > 1) ? path.charAt(1) : 0;
        if (c0 == slash) {
            if (c1 == slash) return 2;  /* Absolute UNC pathname "\\\\foo" */ UNC的絕對路徑
            return 1;                   /* Drive-relative "\\foo" */ 與驅動盤相對路徑
        }
        if (isLetter(c0) && (c1 == ':')) {
            if ((n > 2) && (path.charAt(2) == slash))
                return 3;               /* Absolute local pathname "z:\\foo" */  本地絕對路徑
            return 2;                   /* Directory-relative "z:foo" */  目錄相對路徑
        }
        return 0;                       /* Completely relative */   相對路徑
    }

File(path)各類輸入的path 及其 絕對路徑

 

輸入的path /long  lo/ng \/long long/k  long  D:\JACK\OK \\long(或者\long) //long
this.path \long lo\ng X非法輸入 long\k  long D:\JACK\OK \long \\long
this.PrefixLength 1 0 X 0 0 3 1 2
相關類型 盤相關 項目路徑相關   項目路徑相關 項目路徑相關 徹底絕對路徑 盤相關  
absolutePath D:\long D:\javaTest\long X D:\javaTest\long\k D:\javaTest\long D:\JACK\OK D:\long \\long

 

 

 

 

 

 

總結: 1:輸入path 以'/' 或者 ’\\‘ 開頭的 ,是以項目所在的硬盤位基礎路徑

          2:輸入path 以 字母開頭 的,是以項目的路徑爲基礎路徑 即: System.getProperty("user.dir")

          3.輸入絕對路徑的,就是以該絕對路徑作爲路徑咯

相關文章
相關標籤/搜索