[英]What's the right way of configuring the path to a sqlite database for my servlets to use?
[英]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)
測試此路徑是否以給定路徑開頭。
tl;博士
import static org.assertj.core.api.Assertions.assertThat;
...
assertThat(path2 + "").startsWith("/tmp/"));
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 有路徑友好的方法,比如isDirectory
, startsWith(::Path)
,但根據環境的不同,它們可能導致failed to resolve actual real path
消息。 因此,在斷言之前將Path
轉換為String
更穩定:--通過path2.toString()
或通過path2 + ""
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.