簡體   English   中英

Java 8 中評估 /path/a 是否是 /path 的子目錄的正確方法是什么?

[英]What's the right way in Java 8 to evaluate if /path/a is a subdirectory of /path?

幾乎是標題所要求的。

假設我通過了“/tmp/foo/bar”的路徑,我想特別確保該路徑是路徑“/tmp”的子目錄,最“Java 8”的方式是什么?

具體來說,我有興趣詢問“給定兩個獨立的路徑,/foo 和 /foo/bar/baz,如何在不遞歸目錄樹的情況下測試 /foo/bar/baz 是否是 /foo 的子目錄?” 我對探索 /foo 下的所有子目錄並在下游查找 /foo/bar/baz 不感興趣。

我一直在玩這個想法

@Test
public void test() {
    final Path root = Paths.get("/tmp");
    final Path path0 = Paths.get("/");
    final Path path1 = Paths.get("/opt/location/sub");
    final Path path2 = Paths.get("/tmp/location/sub");

    final Pattern ptrn = Pattern.compile("^[a-zA-Z].*$");

    final Function<Path, String> f = p -> root.relativize(p).toString();

    Assert.assertFalse("root",ptrn.matcher(f.apply(root)).matches());
    Assert.assertFalse("path0",ptrn.matcher(f.apply(path0)).matches());
    Assert.assertFalse("path1",ptrn.matcher(f.apply(path1)).matches());
    Assert.assertTrue("path2",ptrn.matcher(f.apply(path2)).matches());
}

但這感覺就像我一直工作到 Java 8 的邊緣,然后又回到舊模式並錯過了船。

boolean startsWith ( Path other)

測試此路徑是否以給定路徑開頭。

獲取有意義的斷言消息

使用 AssertJ(JUnits 3,4,5+...)

tl;博士

import static org.assertj.core.api.Assertions.assertThat;

    ...
    assertThat(path2 + "").startsWith("/tmp/"));

使用香草 JUnit 4

import static org.junit.Assert.assertThat;        // !DEPRECATED! see: https://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat(T,%20org.hamcrest.Matcher)
import static org.hamcrest.core.StringStartsWith;

    assertThat(path2 + "", startsWith("/tmp/"))

注意:Harmcrest 的 assertThat 已從 JUnit 5 中刪除。因此,在 2020 年,更常見的做法是使用 AssertJ,它更易於未來升級: https ://mvnrepository.com/artifact/org.assertj/assertj-core


詳細信息: Path#startsWith的單元測試問題是它返回布爾值。 所以失敗的測試會返回一個愚蠢的原因:

“預期為真,但為假”

因此,為了更好的單元測試維護/代碼改進,更好的方法是使用斷言框架。 通過這樣的開箱即用的消息傳遞,可以加快您的故障排除速度:

"期望: <"/opt/location/sub">開始於:<"/tmp/foo">。"

注意:雖然 AssertJ 有路徑友好的方法,比如isDirectorystartsWith(::Path) ,但根據環境的不同,它們可能導致failed to resolve actual real path消息。 因此,在斷言之前將Path轉換為String更穩定:--通過path2.toString()或通過path2 + ""

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM