public static String getRelativePath(String fromPath, String toPath,
	    String pathSeparator) throws PathResolutionException {
	if (fromPath.equals(toPath)) {
	    return "";
	}
	// We need the -1 argument to split to make sure we get a trailing
	// "" token if the base ends in the path separator and is therefore
	// a directory. We require directory paths to end in the path
	// separator -- otherwise they are indistinguishable from files.
	String[] from = fromPath.split(Pattern.quote(pathSeparator), -1);
	String[] to = toPath.split(Pattern.quote(pathSeparator), 0);

	// First get all the common elements. Store them as a string,
	// and also count how many of them there are.
	StringBuilder common = new StringBuilder();

	int commonIndex = 0;
	while ((commonIndex < to.length) && (commonIndex < from.length)
		&& (to[commonIndex].equals(from[commonIndex]))) {
	    common.append(to[commonIndex] + pathSeparator);
	    commonIndex++;
	}

	if (commonIndex == 0) {
	    // No single common path element. This most
	    // likely indicates differing drive letters, like C: and D:.
	    // These paths cannot be relativized.
	    throw new PathResolutionException(
		    "No common path element found for '" + toPath + "' and '"
			    + fromPath + "'");
	}

	StringBuffer relative = new StringBuffer();

	if (from.length != commonIndex) {
	    int numDirsUp = from.length - commonIndex - 1;
	    for (int i = 0; i < numDirsUp; i++) {
		relative.append(".." + pathSeparator);
	    }
	}
	int commonLength = common.length();
	if (commonLength < toPath.length()) {
	    relative.append(toPath.substring(commonLength));
	}
	return relative.toString();
    }
public static String getRelativePath ( String fromPath , String toPath , String pathSeparator ) throws PathResolutionException { if ( fromPath . equals ( toPath ) ) { return "" ; } String [ ] from = fromPath . split ( Pattern . quote ( pathSeparator ) , - 1 ) ; String [ ] to = toPath . split ( Pattern . quote ( pathSeparator ) , 0 ) ; StringBuilder common = new StringBuilder ( ) ; int commonIndex = 0 ; while ( ( commonIndex < to . length ) && ( commonIndex < from . length ) && ( to [ commonIndex ] . equals ( from [ commonIndex ] ) ) ) { common . append ( to [ commonIndex ] + pathSeparator ) ; commonIndex ++ ; } if ( commonIndex == 0 ) { throw new PathResolutionException ( "No common path element found for '" + toPath + "' and '" + fromPath + "'" ) ; } StringBuffer relative = new StringBuffer ( ) ; if ( from . length != commonIndex ) { int numDirsUp = from . length - commonIndex - 1 ; for ( int i = 0 ; i < numDirsUp ; i ++ ) { relative . append ( ".." + pathSeparator ) ; } } int commonLength = common . length ( ) ; if ( commonLength < toPath . length ( ) ) { relative . append ( toPath . substring ( commonLength ) ) ; } return relative . toString ( ) ; }
(Found at:
http://stackoverflow.com/questions/204784/how-to-construct-a-relative
-path-in-java-from-two-absolute-paths-or-urls)

Get the relative path from one file to another, specifying the directory
separator. If one of the provided resources does not exist, it is assumed
to be a file unless it ends with '/' or '\'.

@param fromPath
targetPath is calculated to this file
@param toPath
basePath is calculated from this file
@param pathSeparator
directory separator. The platform default is not assumed so
that we can test Unix behaviour when running on Windows (for
example)
@return A {@link String} object is returned containing the relative path.
@throws PathResolutionException
is thrown if the path cannot be resolved.