2009-11-08 10 views
19

Ich habe eine Reihe von Klassen entwickelt, die Dateien in Java manipulieren. Ich arbeite an einer Linux-Box und habe selig getippt new File("path/to/some/file");. Als es an der Zeit war, mich zu verpflichten, erkannte ich, dass einige der anderen Entwickler des Projekts Windows verwenden. Ich möchte nun eine Methode aufrufen, die einen String der Form "/path/to/some/file" aufnehmen und je nach OS einen korrekt getrennten Pfad zurückgeben kann.Gibt es ein Java-Dienstprogramm, das einen String-Pfad konvertiert, um das korrekte File-Trennzeichen zu verwenden?

Zum Beispiel:
"path/to/some/file" wird "path\\to\\some\\file" unter Windows.
Unter Linux gibt es nur die angegebene Zeichenfolge zurück.

Ich weiß, dass es nicht lange dauern würde, um einen regulären Ausdruck, der dies tun könnte, zu knacken, aber ich möchte das Rad nicht neu erfinden und würde eine richtig getestete Lösung bevorzugen. Es wäre schön, wenn es in das JDK eingebaut wäre, aber wenn es Teil einer kleinen F/OSS-Bibliothek ist, ist das auch in Ordnung.

Gibt es also ein Java-Dienstprogramm, das einen String-Pfad konvertiert, um das richtige File-Trennzeichen zu verwenden?

Antwort

32

Apache Commons kommt zur Rettung (wieder). Die Commons IO-Methode FileNameUtils. separatorsToSystem() wird tun, was Sie wollen.

Natürlich wird Apache Commons IO viel mehr tun und lohnt sich zu betrachten.

+9

Warum was darauf hindeutet, Menschen behalte das Hinzufügen aufgebläht Abhängigkeiten ein Schreiben zu vermeiden suchen würde Codezeile? – cletus

+13

Ich betrachte Apache Commons nicht als aufgeblähte Abhängigkeit. Es macht so viel, dass ich Apache Commons Lang und IO als nahezu essentiell betrachte. –

+7

Plus, wie viele Bugs finden Sie in einzelnen Codezeilen? Wie viele Annahmen und Edge-Cases werden verpasst? –

16

A "/path/to/some/file" eigentlich funktioniert unter Windows Vista und XP.

new java.io.File("/path/to/some/file").getAbsoluteFile() 

> C:\path\to\some\file 

Aber es ist noch nicht tragbar als Windows-mehr roots hat. Also muss das Wurzelverzeichnis in irgendeiner Weise ausgewählt werden. Es sollte kein Problem mit relativen Pfaden geben.

Edit:

Apache commons io tut nicht Hilfe bei ENVs andere als Unix & Fenster. Apache io source code:

public static String separatorsToSystem(String path) { 
    if (path == null) { 
    return null; 
    } 
    if (isSystemWindows()) { 
     return separatorsToWindows(path); 
    } else { 
     return separatorsToUnix(path); 
    } 
} 
+0

+1: Genau. Ich wollte diese Antwort posten, bis ich sah, dass es bereits geschehen war. – BalusC

+0

Oh, ich sollte hinzufügen: die Root-Festplatte, die verwendet wird, ist die gleiche Root-Festplatte wie wo das aktuelle Arbeitsverzeichnis ist (von wo Sie den fraglichen Java-Code ausgeführt haben). – BalusC

+1

Wird es auf jeder Plattform funktionieren, die Java unterstützt? – Grundlefleck

2

Haben Sie die Möglichkeit,

System.getProperty("file.separator") 

mit dem String zu bauen, die den Weg stellt?

+0

Ja, aber ich wollte die Saite nicht bauen. Ich vermute, dass dies eine ziemlich gewöhnliche Sache sein muss, ich wollte ein existierendes Code-Snippet wiederverwenden, das den Trick gemacht hat. – Grundlefleck

+1

Wenn Sie den Schrägstrich überall dort verwendet haben, wo Sie einen Pfad haben, scheint dies zu funktionieren. 'String fileSep = System.getProperty (" file.separator "); \t String path = "Pfad/zu/einige/Datei"; \t path.replaceAll ("/", fileSep); ' – Adam

+0

Ja, Thomas Jung erwähnte das in seiner Antwort. War ne Nachricht an mich :) – Grundlefleck

0

Sollte es nicht genug sein zu sagen:

"path"+File.Seperator+"to"+File.Seperator+"some"+File.Seperator+"file" 
+1

Wie ich bereits in anderen Kommentaren erwähnt habe, wusste ich, dass eine einfache String-Ersetzungs-Strategie funktionieren würde, aber das Aufsperren der Zeichenfolge macht den Code weniger lesbar und es gibt eine viel höhere Wahrscheinlichkeit für die Einführung von dummen Tippfehlern . Eine der getesteten und lesbaren Lösungen war eines der Ziele. – Grundlefleck

3

Mit dem neuen Java 7 sie eine Klasse enthalten sind, genannt Pfade diese Ihnen genau das zu tun erlaubt, was Sie wollen (siehe http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html)

hier ein Beispiel ist:

String rootStorePath = Paths.get("c:/projects/mystuff/").toString(); 
+4

Entschuldigung: Dies funktioniert nicht plattformübergreifend. Pfade nimmt das aktuelle Betriebssystem an. Ihr Beispiel sieht wie ein Windows-Pfad aus, aber es hat bereits Linux-Codierungen (weshalb es wahrscheinlich funktioniert hat). Wenn wir einen Windows-Pfad auf einer Linux-Box versuchen, werden die Verzeichnisse nicht interpretiert. ZB "Paths.get" ("c: \\ projects \\ mystuff"). GetParent() gibt null zurück –

3

Dies ist, was Apache commons-io hat, in ein paar Zeilen Code entrollt:

String separatorsToSystem(String path) { 
    if (res==null) return null; 
    if (File.separatorChar=='\\') { 
     // From Windows to Linux/Mac 
     return res.replace('/', File.separatorChar); 
    } else { 
     // From Linux/Mac to Windows 
     return res.replace('\\', File.separatorChar); 
    } 
} 

Wenn Sie also die zusätzliche Abhängigkeit vermeiden möchten, verwenden Sie einfach diese.

2

Für jeden, der versucht später diese 7 Jahre zu tun, die Methode separatorsToSystem Apache Commons hat auf die FilenameUtils Klasse verschoben:

FilenameUtils.separatorsToSystem(String path) 
0
String fileName = Paths.get(fileName).toString(); 

funktioniert perfekt mit dem Windows zumindest auch mit gemischten Pfade, zum Beispiel

c: \ Benutzer \ Benutzername/myproject \ myfiles/myfolder

wird

c:\users\username\myproject\myfiles\myfolder 

Leider überprüfen nicht, was Linux der oben machen würde, aber es wieder Struktur Linux-Datei ist anders, so dass Sie nicht für ein solches Verzeichnis