¿Hay un equivalente de Java para System.IO.Path.Combine()
en C # /. NET? ¿O algún código para lograr esto?
Este método estático combina una o más cadenas en una ruta.
¿Hay un equivalente de Java para System.IO.Path.Combine()
en C # /. NET? ¿O algún código para lograr esto?
Este método estático combina una o más cadenas en una ruta.
Respuestas:
En lugar de mantener todo basado en cadenas, debe usar una clase que esté diseñada para representar una ruta del sistema de archivos.
Si está utilizando Java 7 o Java 8, debería considerar usarlo java.nio.file.Path
; Path.resolve
se puede usar para combinar una ruta con otra o con una cadena. La Paths
clase auxiliar también es útil. Por ejemplo:
Path path = Paths.get("foo", "bar", "baz.txt");
Si necesita atender entornos anteriores a Java-7, puede usar java.io.File
, de esta manera:
File baseDirectory = new File("foo");
File subDirectory = new File(baseDirectory, "bar");
File fileInDirectory = new File(subDirectory, "baz.txt");
Si lo desea de nuevo como una cadena más tarde, puede llamar getPath()
. De hecho, si realmente quisiera imitar Path.Combine
, simplemente podría escribir algo como:
public static String combine(String path1, String path2)
{
File file1 = new File(path1);
File file2 = new File(file1, path2);
return file2.getPath();
}
path2
(ignorando path1
) si path2
es una ruta absoluta. La versión de Java descartará el líder /
o \
y lo tratará como una ruta relativa.
File.getCanonicalPath
.
File
en C # si lo desea. (Estoy asumiendo que quiere decir la existencia de File
un beneficio, que estoy de acuerdo con.)
En Java 7, debe usar resolve
:
Path newPath = path.resolve(childPath);
Si bien la clase de ruta NIO2 puede parecer un poco redundante para File con una API innecesariamente diferente, de hecho es sutilmente más elegante y robusta.
Tenga en cuenta que Paths.get()
(como lo sugirió otra persona) no tiene una sobrecarga tomando un Path
, y hacer Paths.get(path.toString(), childPath)
NO es lo mismo que resolve()
. De los Paths.get()
documentos :
Tenga en cuenta que si bien este método es muy conveniente, su uso implicará una referencia asumida al FileSystem predeterminado y limitará la utilidad del código de llamada. Por lo tanto, no debe usarse en código de biblioteca destinado a reutilización flexible. Una alternativa más flexible es utilizar una instancia de ruta existente como un ancla, como:
Path dir = ... Path path = dir.resolve("file");
La función hermana resolve
es la excelente relativize
:
Path childPath = path.relativize(newPath);
La respuesta principal es usar objetos de archivo. Sin embargo, Commons IO tiene una clase FilenameUtils que puede hacer este tipo de cosas, como el método concat () .
Sé que ha pasado mucho tiempo desde la respuesta original de Jon, pero tenía un requisito similar al OP.
Al extender la solución de Jon, se me ocurrió lo siguiente, que tomará uno o más segmentos de ruta y tomará tantos segmentos de ruta que pueda lanzarle.
Uso
Path.combine("/Users/beardtwizzle/");
Path.combine("/", "Users", "beardtwizzle");
Path.combine(new String[] { "/", "Users", "beardtwizzle", "arrayUsage" });
Codifique aquí para otros con un problema similar
public class Path {
public static String combine(String... paths)
{
File file = new File(paths[0]);
for (int i = 1; i < paths.length ; i++) {
file = new File(file, paths[i]);
}
return file.getPath();
}
}
Enfoque independiente de la plataforma (usa File.separator, es decir, el funcionamiento depende del sistema operativo donde se ejecuta el código:
java.nio.file.Paths.get(".", "path", "to", "file.txt")
// relative unix path: ./path/to/file.txt
// relative windows path: .\path\to\filee.txt
java.nio.file.Paths.get("/", "path", "to", "file.txt")
// absolute unix path: /path/to/filee.txt
// windows network drive path: \\path\to\file.txt
java.nio.file.Paths.get("C:", "path", "to", "file.txt")
// absolute windows path: C:\path\to\file.txt
Para mejorar la respuesta de JodaStephen, Apache Commons IO tiene FilenameUtils que hace esto. Ejemplo (en Linux):
assert org.apache.commons.io.FilenameUtils.concat("/home/bob", "work\\stuff.log") == "/home/bob/work/stuff.log"
Es independiente de la plataforma y producirá los separadores que su sistema necesite.
Aquí hay una solución que maneja múltiples partes del camino y condiciones de borde:
public static String combinePaths(String ... paths)
{
if ( paths.length == 0)
{
return "";
}
File combined = new File(paths[0]);
int i = 1;
while ( i < paths.length)
{
combined = new File(combined, paths[i]);
++i;
}
return combined.getPath();
}
Si no necesita más que cadenas, puede usar com.google.common.io.Files
Files.simplifyPath("some/prefix/with//extra///slashes" + "file//name")
Llegar
"some/prefix/with/extra/slashes/file/name"
Tal vez tarde para la fiesta, pero quería compartir mi opinión sobre esto. Estoy usando un patrón Builder y permito append
llamadas convenientemente encadenadas . Se puede ampliar fácilmente para admitir el trabajo con Path
objetos también.
public class Files {
public static class PathBuilder {
private File file;
private PathBuilder ( File root ) {
file = root;
}
private PathBuilder ( String root ) {
file = new File(root);
}
public PathBuilder append ( File more ) {
file = new File(file, more.getPath()) );
return this;
}
public PathBuilder append ( String more ) {
file = new File(file, more);
return this;
}
public File buildFile () {
return file;
}
}
public static PathBuilder buildPath ( File root ) {
return new PathBuilder(root);
}
public static PathBuilder buildPath ( String root ) {
return new PathBuilder(root);
}
}
Ejemplo de uso:
File root = File.listRoots()[0];
String hello = "hello";
String world = "world";
String filename = "warez.lha";
File file = Files.buildPath(root).append(hello).append(world)
.append(filename).buildFile();
String absolute = file.getAbsolutePath();
El resultado absolute
contendrá algo como:
/hello/world/warez.lha
o tal vez incluso:
A:\hello\world\warez.lha
Esto también funciona en Java 8:
Path file = Paths.get("Some path");
file = Paths.get(file + "Some other path");
Esta solución ofrece una interfaz para unir fragmentos de ruta desde una matriz String []. Utiliza java.io.File.File (String parent, String child) :
public static joinPaths(String[] fragments) {
String emptyPath = "";
return buildPath(emptyPath, fragments);
}
private static buildPath(String path, String[] fragments) {
if (path == null || path.isEmpty()) {
path = "";
}
if (fragments == null || fragments.length == 0) {
return "";
}
int pathCurrentSize = path.split("/").length;
int fragmentsLen = fragments.length;
if (pathCurrentSize <= fragmentsLen) {
String newPath = new File(path, fragments[pathCurrentSize - 1]).toString();
path = buildPath(newPath, fragments);
}
return path;
}
Entonces puedes simplemente hacer:
String[] fragments = {"dir", "anotherDir/", "/filename.txt"};
String path = joinPaths(fragments);
Devoluciones:
"/dir/anotherDir/filename.txt"