2012-07-15 22 views
10

Sto sviluppando un'applicazione Scala su Windows e ho bisogno di inserire un percorso in un file in un modello HTML. Io uso Java io e nio per lavorare con file e percorsi.File.toString o Path.toString di Java con un separatore di percorso specifico

/* 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) 

Il problema è che l'uscita del relativeIncludesPath.toString contiene barre rovesciate \ come separatori - perché l'applicazione funziona su Windows - ma dal momento che il percorso deve essere inserito in un modello HTML, deve contenere le barre / invece.

Poiché non sono riuscito a trovare nulla come file/path.toStringUsingSeparator('/') nella documentazione, attualmente mi sto aiutando con relativeIncludesPath.toString.replace('\\', '/'), che trovo piuttosto poco attraente.

Domanda: Non c'è davvero un modo migliore di utilizzare la sostituzione?

Ho anche sperimentato con Java URI, ma è relativize è incomplete.

+0

Forse mi manca qualcosa. Perché non puoi relativizzare il percorso e quindi usare 'toURI()' invece di usare 'toString()'? – Gene

+0

L'ho provato, ma poi ottengo un URI assoluto che assomiglia a questo: '' file:/C:/root/dir/foo/inc/''. –

+0

Grazie per aver menzionato "URI".Non mi rendevo conto che avrebbe potuto "risolversi", e si scopre che è perfetto per me. –

risposta

4

L'implementazione di Windows dei negozi di interfaccia Path il percorso internamente come una stringa (almeno nel OpenJDK implementation) e semplicemente restituisce tale rappresentazione quando viene chiamato toString(). Ciò significa che non è implicato alcun calcolo e non vi è alcuna possibilità di "configurare" alcun separatore di percorso.

Per questo motivo, concludo che la soluzione è attualmente l'opzione migliore per risolvere il problema.

0

È possibile recuperare la maggior parte delle proprietà di sistema in Java. Date un'occhiata a questo link:

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

si desidera che questo:

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

So che posso ottenere il separatore e posso anche impostarlo globalmente se non sbaglio. Tuttavia, sto cercando un modo per selezionare un separatore specifico per una singola operazione o un singolo oggetto File/Path. –

1

Mi sono appena imbattuto in questo problema. Se si dispone di un percorso relativo, è possibile utilizzare il fatto che lo Path è un Iterable<Path> dei suoi elementi, che segue un elemento radice iniziale facoltativo e quindi può concatenare i pezzi stessi con barre in avanti. Sfortunatamente l'elemento radice può contenere barre, ad es. in Windows si ottengono elementi di root come c:\ e \\foo\bar\ (per percorsi UNC), quindi sembra che non ci sia ancora qualcosa da sostituire con barre in avanti. Ma si potrebbe fare qualcosa di simile ...

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();   
} 

e quando prova con questo codice:

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"); 
} 

ottengo questo:

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 

La sostituzione testuale il backslash con la barra in avanti è decisamente più semplice, ma non ho idea se si possa rompere un caso di sviluppo. (Possono esserci backslash nei percorsi Unix?)