Java tutorial
/* * Copyright (c) 2015 Power Group. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * http://www.apache.org/licenses/LICENSE-2.0 * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.power.commons.io; import org.apache.commons.lang3.StringUtils; import org.power.commons.lang.util.IllegalPathException; import java.io.File; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * ??? * * @author Geiger */ public class FileUtils { // ========================================================================== // // ========================================================================== private static final Pattern schemePrefixPattern = Pattern .compile("(file:/*[a-z]:)|(\\w+://.+?/)|((jar|zip):.+!/)|(\\w+:)", Pattern.CASE_INSENSITIVE); /** * ? * <p> * <code>/</code>??? * </p> * <ol> * <li><code>""</code></li> * <li>backslash("\\")?slash("/")</li> * <li>??"/""\\"</li> * <li>"."?".."?</li> * <li>?"/"?</li> * <li>?".."?</li> * </ol> * * @param path ? * @return ? * @throws IllegalPathException ? */ public static String normalizeAbsolutePath(String path) throws IllegalPathException { return normalizePath(path, true, false, false); } /** * ? * <p> * <code>/</code>??? * </p> * <ol> * <li><code>""</code></li> * <li>backslash("\\")?slash("/")</li> * <li>??"/""\\"</li> * <li>"."?".."?</li> * <li>?"/"?<code>removeTrailingSlash==true</code></li> * <li>?".."?</li> * </ol> * * @param path ? * @param removeTrailingSlash ?<code>"/"</code> * @return ? * @throws IllegalPathException ? */ public static String normalizeAbsolutePath(String path, boolean removeTrailingSlash) throws IllegalPathException { return normalizePath(path, true, false, removeTrailingSlash); } /** * * <p> * ?<code>/</code>?? * </p> * <ol> * <li><code>""</code></li> * <li>backslash("\\")?slash("/")</li> * <li>??"/""\\"</li> * <li>"."?".."?</li> * <li>""</li> * <li>?"/"?</li> * </ol> * * @param path ? * @return ? * @throws IllegalPathException ? */ public static String normalizeRelativePath(String path) throws IllegalPathException { return normalizePath(path, false, true, false); } /** * * <p> * ?<code>/</code>?? * </p> * <ol> * <li><code>""</code></li> * <li>backslash("\\")?slash("/")</li> * <li>??"/""\\"</li> * <li>"."?".."?</li> * <li>""</li> * <li>?"/"?<code>removeTrailingSlash==true</code></li> * </ol> * * @param path ? * @param removeTrailingSlash ?<code>"/"</code> * @return ? * @throws IllegalPathException ? */ public static String normalizeRelativePath(String path, boolean removeTrailingSlash) throws IllegalPathException { return normalizePath(path, false, true, removeTrailingSlash); } /** * * <ol> * <li><code>""</code></li> * <li>backslash("\\")?slash("/")</li> * <li>??"/""\\"</li> * <li>"."?".."?</li> * <li>?"/"""</li> * <li>?"/"?</li> * <li>?".."?</li> * </ol> * * @param path ? * @return ? * @throws IllegalPathException ? */ public static String normalizePath(String path) throws IllegalPathException { return normalizePath(path, false, false, false); } /** * * <ol> * <li><code>""</code></li> * <li>backslash("\\")?slash("/")</li> * <li>??"/""\\"</li> * <li>"."?".."?</li> * <li>?"/"""</li> * <li>?"/"?<code>removeTrailingSlash==true</code></li> * <li>?".."?</li> * </ol> * * @param path ? * @param removeTrailingSlash ?<code>"/"</code> * @return ? * @throws IllegalPathException ? */ public static String normalizePath(String path, boolean removeTrailingSlash) throws IllegalPathException { return normalizePath(path, false, false, removeTrailingSlash); } private static String normalizePath(String path, boolean forceAbsolute, boolean forceRelative, boolean removeTrailingSlash) throws IllegalPathException { char[] pathChars = StringUtils.trimToEmpty(path).toCharArray(); int length = pathChars.length; // ??path"/" boolean startsWithSlash = false; boolean endsWithSlash = false; if (length > 0) { char firstChar = pathChars[0]; char lastChar = pathChars[length - 1]; startsWithSlash = firstChar == '/' || firstChar == '\\'; endsWithSlash = lastChar == '/' || lastChar == '\\'; } StringBuilder buf = new StringBuilder(length); boolean isAbsolutePath = forceAbsolute || !forceRelative && startsWithSlash; int index = startsWithSlash ? 0 : -1; int level = 0; if (isAbsolutePath) { buf.append("/"); } while (index < length) { // ?slash index = indexOfSlash(pathChars, index + 1, false); if (index == length) { break; } // ?slash index int nextSlashIndex = indexOfSlash(pathChars, index, true); String element = new String(pathChars, index, nextSlashIndex - index); index = nextSlashIndex; // "." if (".".equals(element)) { continue; } // ".." if ("..".equals(element)) { if (level == 0) { // ?../?? // ? if (isAbsolutePath) { throw new IllegalPathException(path); } else { buf.append("../"); } } else { buf.setLength(pathChars[--level]); } continue; } // path pathChars[level++] = (char) buf.length(); // ?charslevelindex buf.append(element).append('/'); } // ?"/" if (buf.length() > 0) { if (!endsWithSlash || removeTrailingSlash) { buf.setLength(buf.length() - 1); } } return buf.toString(); } // ========================================================================== // ?basedir // ========================================================================== private static int indexOfSlash(char[] chars, int beginIndex, boolean slash) { int i = beginIndex; for (; i < chars.length; i++) { char ch = chars[i]; if (slash) { if (ch == '/' || ch == '\\') { break; // if a slash } } else { if (ch != '/' && ch != '\\') { break; // if not a slash } } } return i; } /** * ?????basedir * * @param basedir <code>path</code> * @param path ? * @return ? * @throws IllegalPathException ? */ public static String getAbsolutePathBasedOn(String basedir, String path) throws IllegalPathException { // path?? boolean isAbsolutePath = false; path = StringUtils.trimToEmpty(path); if (path.length() > 0) { char firstChar = path.charAt(0); isAbsolutePath = firstChar == '/' || firstChar == '\\'; } if (!isAbsolutePath) { // pathbasedir? if (path.length() > 0) { path = StringUtils.trimToEmpty(basedir) + "/" + path; } else { path = StringUtils.trimToEmpty(basedir); } } return normalizeAbsolutePath(path); } // ========================================================================== // ?basedir // ========================================================================== /** * ?? * * @throws IllegalPathException basedir?? */ public static String getSystemDependentAbsolutePathBasedOn(String basedir, String path) { path = StringUtils.trimToEmpty(path); boolean endsWithSlash = path.endsWith("/") || path.endsWith("\\"); File pathFile = new File(path); if (pathFile.isAbsolute()) { // path?? path = pathFile.getAbsolutePath(); } else { // ?basedir // ??basedir? basedir = StringUtils.trimToEmpty(basedir); File baseFile = new File(basedir); if (baseFile.isAbsolute()) { path = new File(baseFile, path).getAbsolutePath(); } else { throw new IllegalPathException("Basedir is not absolute path: " + basedir); } } if (endsWithSlash) { path = path + '/'; } return normalizePath(path); } // ========================================================================== // ???? // ========================================================================== /** * ? * * @param basedir * @param path ? * @return <code>path</code><code>basedir</code> * <code>basedir</code>?<code>path</code> * @throws IllegalPathException ? */ public static String getRelativePath(String basedir, String path) throws IllegalPathException { // ?basedir?? basedir = normalizeAbsolutePath(basedir); // ?path path = getAbsolutePathBasedOn(basedir, path); // ?path"/" boolean endsWithSlash = path.endsWith("/"); // "/"basedirpath String[] baseParts = StringUtils.split(basedir, '/'); String[] parts = StringUtils.split(path, '/'); StringBuilder buf = new StringBuilder(); int i = 0; while (i < baseParts.length && i < parts.length && baseParts[i].equals(parts[i])) { i++; } if (i < baseParts.length && i < parts.length) { for (int j = i; j < baseParts.length; j++) { buf.append("..").append('/'); } } for (; i < parts.length; i++) { buf.append(parts[i]); if (i < parts.length - 1) { buf.append('/'); } } if (endsWithSlash && buf.length() > 0 && buf.charAt(buf.length() - 1) != '/') { buf.append('/'); } return buf.toString(); } /** * ?? * <ul> * <li>?? - <code>null</code></li> * <li>??? - <code>null</code></li> * </ul> */ public static String getExtension(String fileName) { return getExtension(fileName, null, false); } /** * ?? * <ul> * <li>?? - <code>null</code></li> * <li>??? - <code>null</code></li> * </ul> */ public static String getExtension(String fileName, boolean toLowerCase) { return getExtension(fileName, null, toLowerCase); } /** * ?? * <ul> * <li>?? - <code>null</code></li> * <li>??? - <code>nullExt</code></li> * </ul> */ public static String getExtension(String fileName, String nullExt) { return getExtension(fileName, nullExt, false); } /** * ?? * <ul> * <li>?? - <code>null</code></li> * <li>??? - <code>nullExt</code></li> * </ul> */ public static String getExtension(String fileName, String nullExt, boolean toLowerCase) { fileName = StringUtils.trimToNull(fileName); if (fileName == null) { return null; } fileName = fileName.replace('\\', '/'); fileName = fileName.substring(fileName.lastIndexOf("/") + 1); int index = fileName.lastIndexOf("."); String ext = null; if (index >= 0) { ext = StringUtils.trimToNull(fileName.substring(index + 1)); } if (ext == null) { return nullExt; } else { return toLowerCase ? ext.toLowerCase() : ext; } } /** * ???? * * @param path * @return ? */ public static FileNameAndExtension getFileNameAndExtension(String path) { return getFileNameAndExtension(path, false); } /** * ???? * * @param path * @return ? */ public static FileNameAndExtension getFileNameAndExtension(String path, boolean extensionToLowerCase) { path = StringUtils.trimToEmpty(path); String fileName = path; String extension = null; if (!StringUtils.isEmpty(path)) { // ?index >= 0extension != null?name. int index = path.lastIndexOf('.'); if (index >= 0) { extension = StringUtils.trimToNull(StringUtils.substring(path, index + 1)); if (!StringUtils.containsNone(extension, "/\\")) { extension = null; index = -1; } } if (index >= 0) { fileName = StringUtils.substring(path, 0, index); } } return new FileNameAndExtension(fileName, extension, extensionToLowerCase); } /** * ??? * <ul> * <li></li> * <li>??</li> * <li><code>.</code>?</li> * <li>?<code>null</code></li> * </ul> */ public static String normalizeExtension(String ext) { ext = StringUtils.trimToNull(ext); if (ext != null) { ext = ext.toLowerCase(); if (ext.startsWith(".")) { ext = StringUtils.trimToNull(ext.substring(1)); } } return ext; } /** * ?urlurl<code>URI.resolve()</code> * ????jarURL */ public static String resolve(String url, String relativePath) { url = StringUtils.trimToEmpty(url); Matcher m = schemePrefixPattern.matcher(url); int index = 0; if (m.find()) { index = m.end(); if (url.charAt(index - 1) == '/') { index--; } } return url.substring(0, index) + normalizeAbsolutePath(url.substring(index) + "/../" + relativePath); } public static class FileNameAndExtension { private final String fileName; private final String extension; private FileNameAndExtension(String fileName, String extension, boolean extensionToLowerCase) { this.fileName = fileName; this.extension = extensionToLowerCase ? extension.toLowerCase() : extension; } public String getFileName() { return fileName; } public String getExtension() { return extension; } @Override public String toString() { return extension == null ? fileName : fileName + "." + extension; } } }