Có tương đương với Java không System.IO.Path.Combine()
trong C # /. NET không? Hoặc bất kỳ mã để thực hiện điều này?
Phương thức tĩnh này kết hợp một hoặc nhiều chuỗi thành một đường dẫn.
Có tương đương với Java không System.IO.Path.Combine()
trong C # /. NET không? Hoặc bất kỳ mã để thực hiện điều này?
Phương thức tĩnh này kết hợp một hoặc nhiều chuỗi thành một đường dẫn.
Câu trả lời:
Thay vì giữ mọi thứ dựa trên chuỗi, bạn nên sử dụng một lớp được thiết kế để thể hiện đường dẫn hệ thống tệp.
Nếu bạn đang sử dụng Java 7 hoặc Java 8, bạn nên cân nhắc sử dụng java.nio.file.Path
; Path.resolve
có thể được sử dụng để kết hợp một đường dẫn với một đường dẫn khác hoặc với một chuỗi. Lớp Paths
người trợ giúp cũng hữu ích. Ví dụ:
Path path = Paths.get("foo", "bar", "baz.txt");
Nếu bạn cần phục vụ cho các môi trường tiền Java-7, bạn có thể sử dụng java.io.File
, như thế này:
File baseDirectory = new File("foo");
File subDirectory = new File(baseDirectory, "bar");
File fileInDirectory = new File(subDirectory, "baz.txt");
Nếu bạn muốn nó trở lại như một chuỗi sau này, bạn có thể gọi getPath()
. Thật vậy, nếu bạn thực sự muốn bắt chước Path.Combine
, bạn có thể viết một cái gì đó như:
public static String combine(String path1, String path2)
{
File file1 = new File(path1);
File file2 = new File(file1, path2);
return file2.getPath();
}
path2
(bỏ qua path1
) nếu path2
là một đường dẫn tuyệt đối. Phiên bản Java sẽ bỏ phần đầu /
hoặc \
và coi nó như một đường dẫn tương đối.
File.getCanonicalPath
.
File
trong C # nếu bạn muốn. (Tôi cho rằng bạn có nghĩa là sự tồn tại của File
một lợi ích, mà tôi đồng ý.)
Trong Java 7, bạn nên sử dụng resolve
:
Path newPath = path.resolve(childPath);
Mặc dù lớp Đường dẫn NIO2 có vẻ hơi dư thừa đối với Tệp có API khác nhau không cần thiết, nhưng thực tế nó lại thanh lịch và mạnh mẽ hơn một cách tinh tế.
Lưu ý rằng Paths.get()
(như được đề xuất bởi người khác) không bị quá tải Path
, và thực hiện Paths.get(path.toString(), childPath)
KHÔNG giống như resolve()
. Từ các Paths.get()
tài liệu :
Lưu ý rằng mặc dù phương thức này rất thuận tiện, nhưng sử dụng nó sẽ ngụ ý một tham chiếu giả định đến Hệ thống tệp mặc định và giới hạn tiện ích của mã gọi. Do đó, nó không nên được sử dụng trong mã thư viện dành cho tái sử dụng linh hoạt. Một cách khác linh hoạt hơn là sử dụng một thể hiện Đường dẫn hiện có làm neo, chẳng hạn như:
Path dir = ... Path path = dir.resolve("file");
Chức năng chị em resolve
là tuyệt vời relativize
:
Path childPath = path.relativize(newPath);
Câu trả lời chính là sử dụng các đối tượng File. Tuy nhiên, Commons IO có một lớp FilenameUtils có thể thực hiện loại điều này, chẳng hạn như phương thức concat () .
Tôi biết đã lâu rồi kể từ câu trả lời ban đầu của Jon, nhưng tôi có một yêu cầu tương tự với OP.
Bằng cách mở rộng giải pháp của Jon, tôi đã đưa ra cách sau, việc này sẽ lấy một hoặc nhiều đoạn đường dẫn có nhiều đoạn đường mà bạn có thể ném vào nó.
Sử dụng
Path.combine("/Users/beardtwizzle/");
Path.combine("/", "Users", "beardtwizzle");
Path.combine(new String[] { "/", "Users", "beardtwizzle", "arrayUsage" });
Mã ở đây cho những người khác có vấn đề tương tự
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();
}
}
cách tiếp cận độc lập với nền tảng (sử dụng File.separator, tức là sẽ hoạt động tùy thuộc vào hệ điều hành nơi mã đang chạy:
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
Để nâng cao câu trả lời của JodaStephen, Apache Commons IO có FilenameUtils thực hiện điều này. Ví dụ (trên Linux):
assert org.apache.commons.io.FilenameUtils.concat("/home/bob", "work\\stuff.log") == "/home/bob/work/stuff.log"
Đó là nền tảng độc lập và sẽ tạo ra bất kỳ thiết bị phân tách nào mà hệ thống của bạn cần.
Đây là một giải pháp xử lý nhiều phần đường dẫn và điều kiện cạnh:
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();
}
Nếu bạn không cần nhiều hơn chuỗi, bạn có thể sử dụng com.google.common.io.Files
Files.simplifyPath("some/prefix/with//extra///slashes" + "file//name")
để có được
"some/prefix/with/extra/slashes/file/name"
Có lẽ đến bữa tiệc muộn, nhưng tôi muốn chia sẻ về việc này. Tôi đang sử dụng mẫu Builder và cho phép append
các cuộc gọi được xâu chuỗi thuận tiện . Nó có thể dễ dàng được mở rộng để hỗ trợ làm việc với Path
các đối tượng là tốt.
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);
}
}
Ví dụ về cách sử dụng:
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();
Kết quả absolute
sẽ chứa một cái gì đó như:
/hello/world/warez.lha
hoặc thậm chí có thể:
A:\hello\world\warez.lha
Điều này cũng hoạt động trong Java 8:
Path file = Paths.get("Some path");
file = Paths.get(file + "Some other path");
Giải pháp này cung cấp giao diện để nối các đoạn đường dẫn từ mảng String []. Nó sử dụng java.io.File.File (Chuỗi cha, chuỗi con) :
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;
}
Sau đó, bạn có thể làm:
String[] fragments = {"dir", "anotherDir/", "/filename.txt"};
String path = joinPaths(fragments);
Trả về:
"/dir/anotherDir/filename.txt"