การเข้าร่วมเส้นทางใน Java


100

ในPythonฉันสามารถเข้าร่วมสองเส้นทางด้วยos.path.join:

os.path.join("foo", "bar") # => "foo/bar"

ฉันพยายามที่จะบรรลุเดียวกันใน Java โดยไม่ต้องกังวลถ้าOSเป็นUnix, SolarisหรือWindows:

public static void main(String[] args) {
    Path currentRelativePath = Paths.get("");
    String current_dir = currentRelativePath.toAbsolutePath().toString();
    String filename = "data/foo.txt";
    Path filepath = currentRelativePath.resolve(filename);

    // "data/foo.txt"
    System.out.println(filepath);

}

ผมคาดหวังว่าPath.resolve( )จะเข้าร่วมไดเรกทอรีปัจจุบันของฉัน/home/user/testด้วยการทำdata/foo.txt /home/user/test/data/foo.txtฉันผิดอะไร


1
นี่อาจเป็นสิ่งที่ฉันไม่เห็น เส้นทางปัจจุบันของคุณคือ "" เส้นทางที่สองของคุณคือ "data / foo.txt" บางทีปัญหาของคุณคือดูเหมือนว่าคุณกำลังพิมพ์วัตถุ Path แทนfilepath.toString()
cjds

2
ใช้new File(parent, child)
saka1029

คำตอบ:


103

แม้ว่าโซลูชันดั้งเดิมสำหรับการรับไดเร็กทอรีปัจจุบันโดยใช้empty Stringงาน แต่ขอแนะนำให้ใช้user.dirคุณสมบัติสำหรับไดเร็กทอรีปัจจุบันและuser.homeสำหรับโฮมไดเร็กทอรี

Path currentPath = Paths.get(System.getProperty("user.dir"));
Path filePath = Paths.get(currentPath.toString(), "data", "foo.txt");
System.out.println(filePath.toString());

เอาต์พุต:

/Users/user/coding/data/foo.txt

จากเอกสารคู่มือคลาสJava Path :

เส้นทางจะถือว่าเป็นเส้นทางว่างหากประกอบด้วยองค์ประกอบชื่อเดียวemptyเท่านั้น การเข้าถึงไฟล์โดยใช้empty path is equivalent to accessing the default directoryระบบไฟล์


ทำไมถึงใช้Paths.get("").toAbsolutePath()งานได้

เมื่อสตริงว่างถูกส่งไปยังวัตถุที่Paths.get("")ส่งคืนPathจะมีเส้นทางว่าง แต่เมื่อเราเรียกใช้Path.toAbsolutePath()จะตรวจสอบว่าความยาวของเส้นทางมากกว่าศูนย์หรือไม่มิฉะนั้นจะใช้user.dirคุณสมบัติของระบบและส่งคืนเส้นทางปัจจุบัน

นี่คือรหัสสำหรับการติดตั้งระบบไฟล์ Unix: UnixPath.toAbsolutePath ()


โดยทั่วไปคุณต้องสร้างPathอินสแตนซ์อีกครั้งเมื่อคุณแก้ไขเส้นทางไดเร็กทอรีปัจจุบัน

นอกจากนี้ฉันขอแนะนำให้ใช้File.separatorCharสำหรับรหัสอิสระของแพลตฟอร์ม

Path currentRelativePath = Paths.get("");
Path currentDir = currentRelativePath.toAbsolutePath(); // <-- Get the Path and use resolve on it.
String filename = "data" + File.separatorChar + "foo.txt";
Path filepath = currentDir.resolve(filename);

// "data/foo.txt"
System.out.println(filepath);

เอาท์พุต:

/Users/user/coding/data/foo.txt

ไม่ใช่ฉันอาจมีคนคิดว่าทำงานกับสตริงและseparatorCharด้อยกว่า "นามธรรมระดับสูง" บางอย่างที่ดูเหมือนPathBuilder(currentRelativePath).append("data").append("foo.txt")
jingyu9575

23

Paths#get(String first, String... more) รัฐ

แปลงสตริงพา ธ หรือลำดับของสตริงที่เมื่อรวมเข้ากับสตริงพา ธ เป็นPathไฟล์.

...

การPathแสดงพา ธว่างจะถูกส่งกลับถ้าอันดับแรกเป็นสตริงว่างและมากกว่านั้นไม่มีสตริงที่ไม่ว่าง

System.getProperty("user.dir")ที่จะได้รับไดเรกทอรีที่ใช้ในปัจจุบันคุณสามารถใช้

Path path = Paths.get(System.getProperty("user.dir"), "abc.txt");
System.out.println(path);

นอกจากนี้getวิธีการใช้อาร์กิวเมนต์ตัวแปรความยาวของStringซึ่งจะถูกนำมาใช้เพื่อให้เส้นทางสายที่ตามมา ดังนั้นเพื่อสร้างPathสำหรับ/test/inside/abc.txtคุณต้องใช้มันในทางต่อไปนี้

Path path = Paths.get("/test", "inside", "abc.txt");

9

ไม่ใช่วิธีการเฉพาะ.

หากคุณใช้ java 8 หรือดีกว่าคุณมี 2 ตัวเลือก:

ก) ใช้ java.util.StringJoiner

StringJoiner joiner = new StringJoiner(File.pathSeparator); //Separator
joiner.add("path1").add("path2");
String joinedString = joiner.toString();

b) ใช้ String.join(File.pathSeparator, "path1", "path2");

หากคุณใช้ java 7 หรือต่ำกว่าคุณสามารถใช้ไลบรารี commons-lang จาก apache commons คลาส StringUtils มีวิธีการรวมสตริงโดยใช้ตัวคั่น

ค) StringUtils.join(new Object[] {"path1", "path2"}, File.pathSeparator);

Sidenote: คุณสามารถใช้ linux pathseparator "/" สำหรับ windows ได้ (โปรดจำไว้ว่าพา ธ สัมบูรณ์คือ "/ C: / mydir1 / mydir2" การใช้ always "/" จะมีประโยชน์มากหากคุณใช้โปรโตคอลเช่น file: //


StringJoiner ส่งคืนฉัน/home/user/test:foo.txt
cybertextron

ตัวเลือกที่คุณรู้จักไม่ใช่ตัวเลือกเดียวที่มีอยู่ สามารถใช้ StringBuilder แทน joiner ได้เช่น และในความเป็นจริงการใช้งานของคุณตาม Strings แทนที่จะเป็นไฟล์ / เส้นทางนั้นค่อนข้างไร้เดียงสาและอาจนำไปสู่ปัญหาในหลาย ๆ สถานการณ์
XenoRo

2
File.separatorทำงานให้ฉันแทนFile.pathSeparator
Evan Siroky

ใช้ Pathes.get ("path1", "path2") toAbsolutePath (). toString ()
Erdinc Ay

6

วิธีพื้นฐานที่สุดคือ:

Path filepath = Paths.get("foo", "bar");

Paths.get("")คุณไม่ควรเขียน ฉันประหลาดใจที่ได้ผลเลย หากคุณต้องการอ้างถึงไดเร็กทอรีปัจจุบันอย่างชัดเจนให้ใช้Paths.get(System.getProperty("user.dir")). หากคุณต้องการโฮมไดเร็กทอรีของผู้ใช้ให้ใช้Paths.get(System.getProperty("user.home")).

คุณยังสามารถรวมแนวทาง:

Path filepath = Paths.get(
    System.getProperty("user.home"), "data", "foo.txt");

1

วิธีที่น่าเชื่อถือที่สุดและไม่ขึ้นกับแพลตฟอร์มในการรวมพา ธ ใน Java คือการใช้Path::resolve(ตามที่ระบุไว้ใน JavaDoc สำหรับPaths::get) สำหรับอาร์เรย์ของสตริงที่มีความยาวตามอำเภอใจซึ่งแสดงถึงชิ้นส่วนของเส้นทางสิ่งเหล่านี้สามารถรวมเข้าด้วยกันโดยใช้ Java Stream:

private static final String[] pieces = {
    System.getProperty("user.dir"),
    "data",
    "foo.txt"};
public static void main (String[] args) {
    Path dest = Arrays.stream(pieces).reduce(
    /* identity    */ Paths.get(""),
    /* accumulator */ Path::resolve,
    /* combiner    */ Path::resolve);
    System.out.println(dest);
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.