2012-07-15 2 views
10

Ich entwickle eine Scala-Anwendung unter Windows, und ich muss einen Pfad zu einer Datei in eine HTML-Vorlage einfügen. Ich verwende Javas io und nio, um mit Dateien und Pfaden zu arbeiten.Javas File.toString oder Path.toString mit einem spezifischen Pfadtrennzeichen

/* The paths actually come from the environment. */ 
val includesPath = Paths.get("foo\\inc") 
val destinationPath = Paths.get("bar\\dest") 

/* relativeIncludesPath.toString == "..\\foo\\inc", as expected */ 
val relativeIncludesPath = destinationPath.relativize(includesPath) 

Das Problem ist, dass der Ausgang der relativeIncludesPath.toString Schrägstrich enthält \ als Trennzeichen - weil die Anwendung unter Windows läuft - aber da der Weg in eine HTML-Vorlage eingefügt werden soll, muss es enthält möglicherweise zukunfts / statt Schrägstriche.

Da ich in der Dokumentation nichts wie file/path.toStringUsingSeparator('/') finden konnte, helfe ich mir gerade mit relativeIncludesPath.toString.replace('\\', '/'), was ich eher unattraktiv finde.

Frage: Gibt es wirklich keinen besseren Weg als mit ersetzen?

Ich experimentierte auch mit Javas URI, aber es ist relativize ist incomplete.

+0

Vielleicht vermisse ich etwas. Warum kannst du den Pfad nicht relativieren und dann 'toURI()' anstelle von 'toString()' verwenden? – Gene

+0

Ich habe das versucht, aber dann bekomme ich einen absoluten URI, der so aussieht: '' file:/C:/root/dir/foo/inc/''. –

+0

Danke für die Erwähnung von 'URI'.Ich wusste nicht, dass es "lösen" könnte, und es stellt sich heraus, dass es perfekt für mich ist. –

Antwort

4

Die Windows-Implementierung der Pfad-Schnittstelle speichert den Pfad intern als Zeichenkette (zumindest in der OpenJDK implementation) und einfach gibt diese Darstellung zurück, wenn toString() aufgerufen wird. Dies bedeutet, dass keine Berechnung erforderlich ist und es keine Möglichkeit gibt, ein Pfadtrennzeichen zu "konfigurieren".

Aus diesem Grund schließe ich, dass Ihre Lösung die derzeit beste Lösung ist, um Ihr Problem zu lösen.

0

Sie können die meisten Systemeigenschaften in Java abrufen. Werfen Sie einen Blick auf diesen Link:

http://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html

du wollen:

Key: "file.separator" 
Meaning: Character that separates components of a file path. This is "/" on UNIX and "\" on Windows. 

String sep = System.getProperty("path.separator"); 
+0

Ich weiß, dass ich das Trennzeichen bekommen kann, und ich kann es sogar global einstellen, wenn ich mich nicht irre. Ich suche jedoch nach einer Möglichkeit, ein bestimmtes Trennzeichen für eine einzelne Operation oder ein einzelnes Datei/Pfad-Objekt auszuwählen. –

1

Ich bin gerade in dieses Problem geraten. Wenn Sie einen relativen Pfad haben, können Sie die Tatsache verwenden, dass Path ein Iterable<Path> seiner Elemente ist, gefolgt von einem optionalen anfänglichen Stammelement, und dann können Sie die Stücke selbst mit Schrägstrichen verketten. Leider kann das Wurzelelement Schrägstriche enthalten, z. In Windows erhalten Sie root-Elemente wie c:\ und \\foo\bar\ (für UNC-Pfade), so dass es scheint, egal was Sie noch mit Schrägstrichen ersetzen müssen. Aber Sie könnte etwas tun ...

static public String pathToPortableString(Path p) 
{ 
    StringBuilder sb = new StringBuilder(); 
    boolean first = true; 
    Path root = p.getRoot(); 
    if (root != null) 
    { 
     sb.append(root.toString().replace('\\','/')); 
     /* root elements appear to contain their 
     * own ending separator, so we don't set "first" to false 
     */    
    } 
    for (Path element : p) 
    { 
     if (first) 
      first = false; 
     else 
      sb.append("/"); 
     sb.append(element.toString()); 
    } 
    return sb.toString();   
} 

und wenn ich es mit diesem Code zu testen:

static public void doit(String rawpath) 
{ 
    File f = new File(rawpath); 
    Path p = f.toPath(); 
    System.out.println("Path: "+p.toString()); 
    System.out.println("  "+pathToPortableString(p)); 
} 

static public void main(String[] args) { 
    doit("\\\\quux\\foo\\bar\\baz.pdf"); 
    doit("c:\\foo\\bar\\baz.pdf"); 
    doit("\\foo\\bar\\baz.pdf"); 
    doit("foo\\bar\\baz.pdf"); 
    doit("bar\\baz.pdf"); 
    doit("bar\\"); 
    doit("bar"); 
} 

ich dieses:

Path: \\quux\foo\bar\baz.pdf 
     //quux/foo/bar/baz.pdf 
Path: c:\foo\bar\baz.pdf 
     c:/foo/bar/baz.pdf 
Path: \foo\bar\baz.pdf 
     /foo/bar/baz.pdf 
Path: foo\bar\baz.pdf 
     foo/bar/baz.pdf 
Path: bar\baz.pdf 
     bar/baz.pdf 
Path: bar 
     bar 
Path: bar 
     bar 

Die textliche Substitution Backslash mit Schrägstrich ist definitiv einfacher, aber ich habe keine Ahnung, ob es einen verschlagenen Randfall brechen würde. (Kann es in Unix-Pfaden Backslashes geben?)