为什么在这种情况下 subpath() 会抛出 IllegaArgumentException?

Why is subpath() throwing IllegaArgumentException in this case?

我正在编写一个用于文件夹同步的应用程序。我有两个目录结构,Source 和 Target,在递归另一个目录结构时,我需要以某种方式引用另一个目录结构中的等价 file/folder。此方法试图通过首先提取文件在 Source 中的子位置来实现这一点,方法是将用户先前选择并存储为全局变量的根文件夹移除,然后将其附加到 Target 的根文件夹,这同样是用户全局选择和存储。为什么这不起作用?论点似乎很好;从 sourcePath 的长度到最后一个元素的索引。

private Path getEquivalentFileInTarget(Path pathOfSource) {
    Path sourceSublocation = pathOfSource.subpath(sourcePath.getNameCount(), -1);
    return targetPath.resolve(sourceSublocation);
}

错误日志:

Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
    ... 48 more
Caused by: java.lang.IllegalArgumentException
    at sun.nio.fs.WindowsPath.subpath(WindowsPath.java:634)
    at sun.nio.fs.WindowsPath.subpath(WindowsPath.java:44)
    at sample.FolderSyncerMainWindowController.getEquivalentFileInTarget(FolderSyncerMainWindowController.java:133)
    at sample.FolderSyncerMainWindowController.putInTreeViewCompare(FolderSyncerMainWindowController.java:120)
    at sample.FolderSyncerMainWindowController.handleCompareButton(FolderSyncerMainWindowController.java:92)
... 58 more

subpath方法的第二个参数必须是一个严格大于第一个参数的数字,因为它是子路径元素的索引。没有允许为负的情况。

您应该从计数中减去 1,如下所示:

Path sourceSublocation = pathOfSource.subpath(0, sourcePath.getNameCount()-1);

来自the documentation website

Path subpath(int beginIndex,
           int endIndex)

Parameters:beginIndex - the index of the first element, inclusiveendIndex - the index of the last element, exclusive

Throws:IllegalArgumentException - if beginIndex is negative, or greater than or equal to the number of elements. If endIndex is less than or equal to beginIndex, or larger than the number of elements.

并且由于 endIndex 必须大于 beginIndex 并且 beginIndex 必须大于零,因此 endIndex 也必须大于零并且您通过了 - 1

您在滥用 Path

现在,我不知道您的不同 Path 是否由不同的文件系统提供商发布,但如果不是,您可以这样做:

final Path subpath = sourceRoot.relativize(fullPathInSource);
final Path fullPathInTarget = targetRoot.resolve(subpath);

如果 subpath 是空路径(这就是 sourceRoot.relativize(sourceRoot) 将 return 的路径)。