¿Cuál es la diferencia entre usar File.separator
y un normal /
en un Java Path-String?
A diferencia de la \\
plataforma de doble barra diagonal inversa , la independencia no parece ser la razón, ya que ambas versiones funcionan en Windows y Unix.
public class SlashTest {
@Test
public void slash() throws Exception {
File file = new File("src/trials/SlashTest.java");
assertThat(file.exists(), is(true));
}
@Test
public void separator() throws Exception {
File file = new File("src" + File.separator + "trials" + File.separator + "SlashTest.java");
assertThat(file.exists(), is(true));
}
}
Para reformular la pregunta, si /
funciona en Unix y Windows, ¿por qué debería alguien querer usar File.separator
?
Respuestas:
Con las bibliotecas de Java para manejar archivos, puede usar de forma segura
/
(barra inclinada, no barra invertida) en todas las plataformas. El código de la biblioteca se encarga de traducir las cosas en rutas específicas de la plataforma internamente.File.separator
Sin embargo, es posible que desee usar en la interfaz de usuario, porque es mejor mostrar a las personas lo que tendrá sentido en su sistema operativo, en lugar de lo que tiene sentido para Java.Actualización : no he podido, en cinco minutos de búsqueda, encontrar documentado el comportamiento de "siempre se puede usar una barra oblicua". Ahora, estoy seguro de que lo he visto documentado, pero en ausencia de encontrar una referencia oficial (porque mi memoria no es perfecta), me quedaría con el uso
File.separator
porque sabes que funcionará.fuente
File
utilizaFileSystem.normalize
todo el lugar para "normalizar" las rutas recibidas a través de la API pública, y casi todo lo que se ocupa de cadenas de ruta de archivo (por ejemploFileWriter(String)
) se utilizaFile
debajo de las cubiertas.File
.Usas
File.separator
porque algún día tu programa podría ejecutarse en una plataforma desarrollada en una tierra lejana, una tierra de cosas extrañas y personas extrañas, donde los caballos lloran y las vacas operan todos los ascensores. En esta tierra, la gente ha usado tradicionalmente el carácter ":" como un separador de archivos, y tan obedientemente la JVM obedece sus deseos.fuente
Aunque usar File.separator para hacer referencia a un nombre de archivo es excesivo (para aquellos que imaginan tierras lejanas, imagino que su implementación de JVM reemplazaría a
/
con un:
al igual que el jvm de Windows lo reemplaza con a\
).Sin embargo, a veces obtiene la referencia del archivo, no la crea, y necesita analizarlo, y para poder hacerlo, necesita conocer el separador en la plataforma. File.separator te ayuda a hacer eso.
fuente
OK, inspeccionemos un código.
File.java
líneas 428 a 435 enFile.<init>
:Y leamos los
fs/*(FileSystem)*/.fromURIPath()
documentos:Esto significa
FileSystem.fromURIPath()
que el procesamiento posterior en la ruta URI solo en Windows, y porque en la siguiente línea:Reemplaza cada '/' con un sistema dependiente
seperatorChar
, siempre puede estar seguro de que '/' es seguro en cada sistema operativo.fuente
Bueno, hay más sistemas operativos que Unix y Windows (dispositivos portátiles, etc.), y Java es conocido por su portabilidad. La mejor práctica es usarlo, para que la JVM pueda determinar cuál es el mejor para ese sistema operativo.
fuente
:
separadores de estilo Mac han desaparecido hace mucho tiempo. Parece que todos menos Windows usan el estándar/
más. E incluso Windows parece manejar bien las barras ahora. Pruebecd /windows/system
en un sistema Windows 10 desde la unidad del sistema principal. Si bien aún desea mostrar rutas utilizando el separador del sistema (para no confundir a sus usuarios), puede usar la barra diagonal en/
cualquier otro lugar y estar seguro de que su código funcionará en cualquier lugar donde pueda implementarlo.Aunque no hace mucha diferencia en el camino de regreso, sí lo hace en el camino de regreso.
Claro que puede usar '/' o '\' en un nuevo archivo (ruta de cadena), pero File.getPath () solo le dará uno de ellos.
fuente
/
hacia adelante o hacia atrás\\
. Pero en cualquier otro lugar, es mejor que uses la barra diagonal/
o tendrás problemas.Tarde a la fiesta. Estoy en Windows 10 con JDK 1.8 y Eclipse MARS 1.
Me parece que
getClass().getClassLoader().getResourceAsStream("path/to/resource");
funciona y
getClass().getClassLoader().getResourceAsStream("path"+File.separator+"to"+File.separator+"resource");
no funciona y
getClass().getClassLoader().getResourceAsStream("path\to\resource");
No funciona. Los dos últimos son equivalentes. Entonces ... tengo buenas razones para NO usar File.separator.
fuente
getClass().getClassLoader().getResourceAsStream("path\to\resource");
, hay una tabulación (\t
) y un retorno de carro (\r
).File.separator
es una barra invertida. Es solo en cadenas codificadas donde se trata como un personaje de escape donde necesita escapar de la barra invertida. Si ha almacenado el carácter en un archivo de texto, o en unchar
o,String
entonces no necesita escapar por segunda vez ya que ya se ha convertido al carácter de barra invertida esperado. Prueba esto para verlo por ti mismo:String backslash = "\\"; System.out.println("welcome" + backslash + "to" + backslash + "reality");
portabilidad simple y llanamente.
fuente
/
o el separador del sistemaFile.separator
. Ambos parecen funcionar en todas partes. MientrasFile.separator
está garantizado que funciona en todas partes, la barra simple/
también parece funcionar en todas partes. Si no funciona en algún lugar, me encantaría saberlo. Creo que funcionará en todos los sistemas. Por lo menos, aún no he encontrado ningún lugar que/
no funcione (Mac OSX, Windows, * nix, Android, iOS; sin embargo, no he comprobado las Macs OSX anteriores que usaban ":" como separador, OS / 2, NeXT, o cualquiera de los otros sistemas operativos realmente antiguos)."Java SE8 para programadores" afirma que Java hará frente a cualquiera de los dos. (págs. 480, último párrafo). El ejemplo afirma que:
analizará muy bien. Tome nota del último separador (estilo Unix).
Es de mal gusto, y probablemente propenso a errores, pero es lo que afirman (Deitel y Deitel).
Creo que la confusión para las personas, en lugar de Java, es razón suficiente para no usar esta función (¿errada?).
fuente
Como los caballeros describieron la diferencia con detalles variantes.
Me gustaría recomendar el uso de la clase io api de Apache Commons
FilenameUtils
cuando se trata de archivos en un programa con la posibilidad de desplegarse en múltiples sistemas operativos.fuente
El nombre de ruta para un archivo o directorio se especifica utilizando las convenciones de nomenclatura del sistema host. Sin embargo, la clase File define constantes dependientes de la plataforma que se pueden usar para manejar nombres de archivos y directorios de manera independiente de la plataforma.
Files.seperator define el carácter o cadena que separa el directorio y los componentes del archivo en un nombre de ruta. Este separador es '/', '\' o ':' para Unix, Windows y Macintosh, respectivamente.
fuente
Si está utilizando Java 7, vaya a Path.resolve () y Paths.get () .
fuente
Usando File.separator, Ubuntu generó archivos con "\" en su nombre en lugar de directorios. Tal vez estoy siendo flojo con la forma en que estoy creando archivos (y directorios) y podría haberlo evitado, independientemente, use "/" cada vez para evitar archivos con "\" en su nombre
fuente
Si está intentando crear un archivo desde una ruta preparada (guardada en la base de datos, por ejemplo) usando el separador de Linux, ¿qué debo hacer?
Tal vez solo use la ruta para crear el archivo:
Pero Windows usa un separador diferente (
\
). Entonces, ¿la alternativa es convertir el separador de barras en una plataforma independiente? Me gusta:Este método
convertPathToPlatformIndependent
probablemente tendrá algún tipo de división por "/" y se unirá con File.separator.Bueno, para mí, eso no es bueno para un lenguaje que es independiente de la plataforma (¿verdad?) Y Java ya es compatible
/
con Windows o Linux. Pero si está trabajando con rutas y necesita recordar esta conversión cada vez, esto será una pesadilla y no tendrá ninguna ganancia real para la aplicación en el futuro (tal vez en el universo que describió @Pointy).fuente