1

I want to write an algorithm to convert an arbitrary filepath to canonical form (i.e. remove any "." and ".." where "." means "current directory", and ".." means "up one level"). I've removed the "." correctly, that part's easy.

For example:

/web/foo/bar/../baz/../../blat/./../foobie/bletch.html

should become

/web/foobie/bletch.html

and

www/someDir/./index.html

should become

www/someDir/index.html

and

www/someDir/./index.html

should become

www/index.html

This is my code so far:

public static String makeCanonical(String uri) {
    String canonical="";
    System.out.println("+" + uri); //for testing, doesn't need to print
    ArrayList<String> parts=new ArrayList<String>();
    int currentIndex=0;

    //split string at every '/' into an ArrayList substring
    for(int i=0; i<uri.length(); i++){
        if(uri.charAt(i)=='/'){
            parts.add(uri.substring(currentIndex, i+1));
            currentIndex=i+1;

        }
    }
    //trying to go up one level at every '..'  ;  not working correctly
    for(int i=0; i<parts.size(); i++){
        if(parts.get(i).contains("..")){
            parts.remove(i);
            parts.remove(i-1);
        }
    }
    //compile all parts into single string
    for(int i=0; i<parts.size(); i++){
        canonical=canonical+parts.get(i);
    }
    //discard and '.' (single dot) characters
    canonical=canonical.replaceAll("/./", "/");
    if(canonical.contains(".")){

    }
    System.out.print("-" + canonical); //printing for testing
    System.out.println();
    System.out.println();
    return canonical;
}

This is my output in the form

+(original)
-(output)

-

+www/index.html
-www/

+/web/foo/bar/../baz/../../blat/./../foobie/bletch.html
-/web/foo/baz/blat/foobie/

+www/someDir/
-www/someDir/

+www/someDir/anotherDir/../../index.html
-www/someDir/../
Mat Jones
  • 936
  • 1
  • 10
  • 27
  • 3
    This is an exercise? Why aren't you using `java.nio.file.Path`? Or looking at some of its built-in implementations? – Sotirios Delimanolis Dec 01 '15 at 00:47
  • That's a start. Now, what's wrong with your attempt? – Sotirios Delimanolis Dec 01 '15 at 01:17
  • this is homework? you can't use any builtin functionality? – jtahlborn Dec 01 '15 at 01:26
  • Another bug you've not discovered as far as I can see: `replaceAll("/./", ...` applied to `/x/` would result in `/` because that method assumes you're providing a regular expression and `.` means "any character" not the literal `.`. – zapl Dec 01 '15 at 01:27
  • No, we can't use a built-in functionality. It's part of a larger assignment, we have to write this method. – Mat Jones Dec 01 '15 at 01:27
  • @zapl how do I denote the literal `.`? – Mat Jones Dec 01 '15 at 01:28
  • 1
    http://stackoverflow.com/questions/3674930/java-regex-meta-character-and-ordinary-dot e.g. `replaceAll("/\\./"` or use `.replace("/./", "/")` which also replaces all but does not assume regex syntax and is a wonderful example of inconstistent naming. – zapl Dec 01 '15 at 01:30
  • Okay. any idea how to fix the other issue? – Mat Jones Dec 01 '15 at 01:32
  • How does `www/someDir/./index.html` become `www/index.html`? – fge Dec 01 '15 at 17:37
  • Which version of Java is that by the way? If this is Java 8 you can use a `Collector` to great effect here – fge Dec 01 '15 at 17:40
  • I outlined the basic algorithm for doing this in an [answer to a PHP question](http://stackoverflow.com/a/14883803/862594) – nickb Dec 01 '15 at 18:11

0 Answers0