2009-11-08 6 views
19

He desarrollado varias clases que manipulan archivos en Java. Estoy trabajando en una caja de Linux, y he estado felizmente escribiendo new File("path/to/some/file");. Cuando llegó el momento de comprometerme, me di cuenta de que algunos de los otros desarrolladores del proyecto están usando Windows. Ahora me gustaría llamar a un método que puede tomar una cadena del formulario "/path/to/some/file" y, dependiendo del sistema operativo, devolver una ruta correctamente separada.¿Hay una utilidad de Java que convierta una ruta de cadena para usar el separador de separador de archivos correcto?

Por ejemplo:
"path/to/some/file" se convierte en "path\\to\\some\\file" en Windows.
En Linux, simplemente devuelve la cadena especificada.

Me doy cuenta de que no tardaría en levantar una expresión regular que podría hacer esto, pero no estoy buscando reinventar la rueda, y preferiría una solución probada adecuadamente. Sería bueno si estuviera integrado en el JDK, pero si es parte de una pequeña biblioteca F/OSS también está bien.

Entonces, ¿hay una utilidad de Java que convierta una ruta de Cadena para utilizar el separador de archivos de caracteres correcto?

Respuesta

32

Apache Commons viene al rescate (nuevamente). El método IO de Commons FileNameUtils. separatorsToSystem() hará lo que quieras.

No hace falta decir que Apache Commons IO hará mucho más y vale la pena mirar.

+9

¿Por qué la gente sigue lo que sugiere la adición de dependencias hinchados evitar escribir uno línea de código? – cletus

+13

No considero a Apache Commons como una dependencia hinchada. Hace tanto que tiendo a considerar a Apache Commons Lang e IO como casi esenciales hoy en día. –

+7

Además, ¿cuántos errores encuentra en líneas únicas de código? ¿Cuántas suposiciones y casos extremos se olvidan? –

16

A "/path/to/some/file" en realidad funciona en Windows Vista y XP.

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

> C:\path\to\some\file 

pero sigue siendo no es portátil como Windows tiene múltiples roots. Por lo tanto, el directorio raíz debe seleccionarse de alguna manera. No debería haber problemas con las rutas relativas.

Editar:

Apache Commons io hace no ayuda con envs distintos de UNIX & ventanas. 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: Exactamente. Estaba a punto de publicar esta respuesta hasta que vi que una ya lo hizo. – BalusC

+0

Ah, debería agregar: el disco raíz que se utilizará es el mismo disco raíz que el directorio de trabajo actual (desde donde ha ejecutado el código Java en cuestión). – BalusC

+1

¿Funcionará en todas las plataformas que soportan Java? – Grundlefleck

2

¿Tiene la opción de usar

System.getProperty("file.separator") 

para crear la cadena que representa la ruta?

+0

Sí, pero no quería construir la cadena. Adivinando que esto debe ser algo bastante común, quería reutilizar un fragmento de código existente que funcionó. – Grundlefleck

+1

Si ha utilizado la barra diagonal en todas partes tiene una ruta, esto parece funcionar. 'String fileSep = System.getProperty (" file.separator "); \t String path = "path/to/some/file"; \t path.replaceAll ("/", fileSep); ' – Adam

+0

Sí, Thomas Jung lo mencionó en su respuesta. Fue una novedad para mí :) – Grundlefleck

0

¿No debería ser suficiente para decir:

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

Como mencioné en otros comentarios, sí, sabía que una estrategia simple de reemplazo de cadenas funcionaría, pero si piratear la cadena hace que el código sea menos legible, y hay muchas más posibilidades de introducir estúpidos errores tipográficos . El uso de una solución que fue probada y legible fue uno de los objetivos aquí. – Grundlefleck

3

Con el nuevo Java 7 que han incluido una clase llamada Caminos esto le permite hacer exactamente lo que quiere (ver http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html)

aquí es un ejemplo:

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

Lo sentimos: esto no funciona multiplataforma. Paths asume el sistema operativo actual. Su ejemplo parece una ruta de Windows, pero ya tiene codificaciones de Linux (que probablemente sea la razón por la que funcionó). Si probamos una ruta de Windows en un cuadro de Linux, no interpretará los directorios. Por ejemplo, Paths.get ("c: \\ projects \\ mystuff"). GetParent() devuelve null –

3

Esto es lo que hace Apache commons-io, desenrollado en un par de líneas de código:

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

Así que si quiere evitar la dependencia adicional, solo use eso.

2

para cualquiera que trate de hacer esto 7 años más tarde, el método de los bienes comunes de Apache separatorsToSystem se ha trasladado a la clase FilenameUtils:

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

funciona perfectamente en Windows, al menos, incluso con trayectos mixtos, por ejemplo

C: \ Users \ nombre de usuario/miproyecto \ myfiles/myfolder

convierte

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

En este momento no han Linux comprobar lo haría de lo anterior, pero allí de nuevo la estructura de archivos de Linux es diferente por lo que no buscar un directorio

Cuestiones relacionadas