Java 路径中的错误';s.relatize()文档还是我在这里做了一些明显错误的事情?

Java 路径中的错误';s.relatize()文档还是我在这里做了一些明显错误的事情?,java,filesystems,java.nio.file,Java,Filesystems,Java.nio.file,好吧,这里有一些有趣的事情。注意这里的“元素”是PathElements的一个实例,对于这些.resolve()和.relative()是和。。。相关方法实现的链接 失败的试验方法摘录: /* * This test this part of the Path's .relativize() method: * * <p> For any two {@link #normalize normalized} paths <i>p</i> and * &l

好吧,这里有一些有趣的事情。注意这里的“元素”是
PathElements
的一个实例,对于这些
.resolve()
.relative()
是和。。。相关方法实现的链接

失败的试验方法摘录:

/*
 * This test this part of the Path's .relativize() method:
 *
 * <p> For any two {@link #normalize normalized} paths <i>p</i> and
 * <i>q</i>, where <i>q</i> does not have a root component,
 * <blockquote>
 * <i>p</i><tt>.relativize(</tt><i>p</i><tt>.resolve(</tt><i>q</i><tt>))
 * .equals(</tt><i>q</i><tt>)</tt>
 * </blockquote>
 *
 * Unfortunately, that turns out NOT TO BE TRUE! Whether p is absolute or
 * relative, it is indeed the case that the path elements (root, names) are
 * the same but the filesystem DIFFERS.
 *
 * An as Path's .equals() requires that the two filesystems be equal in
 * order for two Paths to be equals, this contract can not be obeyed; or I
 * am doing something VERY wrong.
 */
@Test(enabled = false)
public void relativizeResolveRoundRobinWorks()
{
    /*
     * In order to set up the environment we define a mock
     * FileSystemProvider which both our mock filesystems will return when
     * .provider() is called.
     *
     * We also suppose that the same PathElementsFactory is used; while this
     * code is not written yet, there should be only one such factory per
     * FileSystemProvider anyway (which is fed into all generated FileSystem
     * instances -- at least that's the plan).
     *
     * Note that this test method assumes that .equals() and .hashCode() are
     * not implemented on GenericPath. As such we check that the FileSystem
     * is the same (this is required by Path's equals()) and that the path
     * elements are the same (this is this package's requirements).
     */
    final FileSystemProvider fsProvider = mock(FileSystemProvider.class);
    final PathElementsFactory elementsFactory
        = new UnixPathElementsFactory();
    final FileSystem fsForP = mock(FileSystem.class);
    final FileSystem fsForQ = mock(FileSystem.class);

    when(fsForP.provider()).thenReturn(fsProvider);
    when(fsForQ.provider()).thenReturn(fsProvider);

    /*
     * The path to be operated. As the contract says, it has no root
     * component.
     */
    final GenericPath q = new GenericPath(fsForQ, elementsFactory,
        new PathElements(null, new String[] { "q1", "q2" }));

    /*
     * The path against which both resolution and relativization are
     * performed. We take two versions of it: a non absolute one and an
     * absolute one.
     *
     * Note that since we use a UnixPathElementsFactory, we equate an
     * absolute path (or not) to a path which has a root component (or not).
     */
    GenericPath p;
    // "rr" as in "resolved, relativized"
    GenericPath rr;

    final CustomSoftAssertions soft = CustomSoftAssertions.create();

    /*
     * Try with the absolute version first...
     */
    p = new GenericPath(fsForP, elementsFactory,
        new PathElements("/", new String[] { "p1", "p2" }));
    rr = (GenericPath) p.relativize(p.resolve(q));

    soft.assertThat(rr.getFileSystem())
        .as("rr and q filesystems should be the same (p absolute)")
        .isSameAs(q.getFileSystem());
    soft.assertThat(rr.elements).hasSameContentsAs(q.elements);

    /*
     * Now with the non absolute version
     */
    p = new GenericPath(fsForP, elementsFactory,
        new PathElements(null, new String[] { "p1", "p2" }));
    rr = (GenericPath) p.relativize(p.resolve(q));

    soft.assertThat(rr.getFileSystem())
        .as("rr and q filesystems should be the same (p not absolute)")
        .isSameAs(q.getFileSystem());
    soft.assertThat(rr.elements).hasSameContentsAs(q.elements);

    soft.assertAll();
}
/*
*此测试路径的.relativize()方法的这一部分:
*
*对于任意两个{@link#normalize normalize}路径p和
*q,其中q没有根分量,
* 
*p.相对化(p.解析(q))
*.等于(q)
* 
*
*不幸的是,事实证明并非如此!p是绝对值还是绝对值
*相对而言,路径元素(根、名称)确实是
*相同,但文件系统不同。
*
*as路径的.equals()要求这两个文件系统的大小相等
*如果两条路径相等,则无法遵守本合同;或者我
*我做错了什么事。
*/
@测试(已启用=错误)
公共无效相对化解决方案Robinworks()
{
/*
*为了设置环境,我们定义了一个模拟
*FileSystemProvider,我们的两个模拟文件系统将在
*.provider()被调用。
*
*我们还假设使用相同的PathElementsFactory;而
*代码尚未编写,每个工厂应该只有一个这样的工厂
*FileSystemProvider(它被馈送到所有生成的文件系统中
*实例——至少这是计划)。
*
*请注意,此测试方法假定.equals()和.hashCode()是
*未在GenericPath上实现。因此,我们检查文件系统
*相同(这是路径的equals()所要求的),并且
*元素相同(这是本包的要求)。
*/
final FileSystemProvider fsProvider=mock(FileSystemProvider.class);
最终路径元素工厂元素工厂
=新的UnixPathElementsFactory();
最终文件系统fsForP=mock(FileSystem.class);
最终文件系统fsForQ=mock(FileSystem.class);
when(fsForP.provider())。然后返回(fsProvider);
when(fsForQ.provider())。然后返回(fsProvider);
/*
*要操作的路径。正如合同所说,它没有根
*组成部分。
*/
最终通用路径q=新的通用路径(fsForQ、elementsFactory、,
新的PathElements(null,新字符串[]{“q1”,“q2”});
/*
*解析和相对化的路径
*执行。我们采用两种版本:非绝对版本和非绝对版本
*绝对一号。
*
*请注意,由于我们使用的是UnixPathElementsFactory,因此我们将
*绝对路径(或非绝对路径)指向具有根组件(或非根组件)的路径。
*/
一般路径;
//“rr”如“已解决,相对化”
一般路径rr;
final CustomSoftAssertions soft=CustomSoftAssertions.create();
/*
*首先尝试绝对版本。。。
*/
p=新的通用路径(fsForP、elementsFactory、,
新的PathElements(“/”,新的字符串[]{“p1”,“p2”});
rr=(GenericPath)p.relativize(p.resolve(q));
assertThat(rr.getFileSystem())
.as(“rr和q文件系统应相同(p绝对)”)
.isSameAs(q.getFileSystem());
软资产(rr.elements)、hasSameContentsAs(q.elements);
/*
*现在是非绝对版本
*/
p=新的通用路径(fsForP、elementsFactory、,
新的PathElements(null,新字符串[]{“p1”,“p2”});
rr=(GenericPath)p.relativize(p.resolve(q));
assertThat(rr.getFileSystem())
.as(“rr和q文件系统应该相同(p不是绝对的)”)
.isSameAs(q.getFileSystem());
软资产(rr.elements)、hasSameContentsAs(q.elements);
soft.assertAll();
}
此测试失败,原因是:

org.assertj.core.api.SoftAssertionError: 
The following 2 assertions failed:
1) [rr and q filesystems should be the same (p absolute)] 
Expecting:
 <Mock for FileSystem, hashCode: 1125642929>
and actual:
 <Mock for FileSystem, hashCode: 1497261280>
to refer to the same object
2) [rr and q filesystems should be the same (p not absolute)] 
Expecting:
 <Mock for FileSystem, hashCode: 1125642929>
and actual:
 <Mock for FileSystem, hashCode: 1497261280>
to refer to the same object
org.assertj.core.api.SoftAssertionError:
以下2个断言失败:
1) [rr和q文件系统应相同(p绝对值)]
期望:
和实际:
指同一对象
2) [rr和q文件系统应该相同(p不是绝对的)]
期望:
和实际:
指同一对象
显然如此

  • r=p.resolve(q)将给出与p共享同一文件系统的路径,而不是q
  • 因此,p.relatize(r)也将给出一个与p具有相同文件系统的路径
  • 但是路径契约要求,为了使两条路径相等,它们共享同一个文件系统
在这种情况下,这总是错误的


那么,这是文档中一个明显的错误还是我忽略了什么?

a:文档中没有提到来自其他文件系统的路径

关于resolve和relativize的文档在这里并不十分清楚。 但如果参数路径来自不同的文件系统,则resolve和relativize必须抛出ProviderMismatchException。 你的考试应该早点结束

路径上的约束在不同的文件系统之间可能有很大的不同。考虑相对应的情况。可以从一个文件系统走到另一个不相交的文件系统的路径应该是什么样子


注意:我测试了几个文件系统实现,所有的都是这种情况。

您混合了文件系统提供程序和文件系统。提供者完全有可能创建多个文件系统(例如附带的JDK zip提供者)。@fge一个提供者可以创建多个文件系统,这是正确的。在这种情况下,决心可以起作用,但我仍然认为相对主义必须放弃;现在已经太迟了,对吗?;)无论如何,我已经在我的java7 fs more包中解决了这个问题。。。