Here you can find the source of normalizeAbsolutePath(String curDir)
Parameter | Description |
---|---|
curDir | The non-normalized path. |
public static String normalizeAbsolutePath(String curDir)
//package com.java2s; /******************************************************************************* * Copyright (c) 2011 Arapiki Solutions Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors:/*from w w w . j a v a 2s.c om*/ * "Peter Smith <psmith@arapiki.com>" - initial API and * implementation and/or initial documentation *******************************************************************************/ import java.util.EmptyStackException; import java.util.Stack; public class Main { /** * Given an absolute path (starting with '/'), normalize it so that there * are no ".." or "." components, and no excess / characters. Note that unlike * File.getCanonicalPath(), we do not access the underlying file system * (this allows us to process content on a different machine from which the * path actually exists). * * @param curDir The non-normalized path. * @return The normalized path. */ public static String normalizeAbsolutePath(String curDir) { /* * This algorithm involves scanning through a StringBuffer (buf) and * keep track of the various '/' characters found (these delineate the * various path components). There are several cases to handle: 1) * Component "." is found - simply delete it and keep scanning. 2) * Component "/" is found - this is an excessive /, and can also be * deleted. 3) Component ".." is found - we need to backtrack and delete * the previous component as well. * * We use two pointers (thisIndex, nextIndex) to track the start and end * of each component. We also use a Stack (slashStack) to record the * positions of all previous / characters, in case we need to backtrack. */ if (curDir == null) { return null; } StringBuffer buf = new StringBuffer(curDir); int maxIndex = buf.length(); int thisIndex = buf.indexOf("/"); Stack<Integer> slashStack = new Stack<Integer>(); /* * While not at the end of the string yet, keep looking for more * components. */ while ((thisIndex != -1) && (thisIndex != maxIndex)) { /* * Find the next / character. If there aren't any more, use the end * of string. This will allow us to find the next "component" * (between slashes). */ int nextIndex = buf.indexOf("/", thisIndex + 1); if (nextIndex == -1) { nextIndex = maxIndex; } String pathPart = buf.substring(thisIndex, nextIndex); /* a path component of "/." or "/" should be removed */ if (pathPart.equals("/.") || pathPart.equals("/")) { buf.delete(thisIndex, nextIndex); maxIndex -= (nextIndex - thisIndex); /* a path component of "/.." involves going backwards */ } else if (pathPart.equals("/..")) { /* * Find the index of the previous component's starting point by * popping the stack. If we go off the end of the stack, use * index 0 instead. This allows for paths like "/../.." that are * still legal in Linux. */ int lastIndex; try { lastIndex = slashStack.pop(); } catch (EmptyStackException ex) { lastIndex = 0; } buf.delete(lastIndex, nextIndex); maxIndex -= (nextIndex - lastIndex); thisIndex = lastIndex; } else { /* * normal case - record the slash position (in case we see a * future ..) and move on */ slashStack.push(Integer.valueOf(thisIndex)); thisIndex = nextIndex; } } /* * Return the normalized string. Note the special cases of "/.." that * should result in "/". */ if (buf.length() == 0) { return "/"; } else { return buf.toString(); } } }