2015-09-30 2 views
0

У меня возникли проблемы с обложкой от URI до nio.Path в общем случае. Учитывая URI с несколькими схемами, я хочу создать один экземпляр nio.Path, чтобы отразить этот URI.Преобразование JAR-URI в nio.Path

//setup 
    String jarEmbeddedFilePathString = "jar:file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml"; 
    URI uri = URI.create(jarEmbeddedFilePathString); 

    //act 
    Path nioPath = Paths.get(uri); 

    //assert --any of these are acceptable 
    assertThat(nioPath).isEqualTo("C:/Program Files (x86)/OurSoftware/OurJar_x86_1.0.68.220.jar/com/our_company/javaFXViewCode.fxml"); 
    //--or assertThat(nioPath).isEqualTo("/com/our_company/javaFXViewCode.fxml"); 
    //--or assertThat(nioPath).isEqualTo("OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml") 
    //or pretty well any other interpretation of jar'd-uri-to-path any reasonable person would have. 

Этот код в настоящее время бросает FileSystemNotFoundException на Paths.get() вызова.

Фактическая причина этого преобразования заключается в том, чтобы задать результирующий путь о вещах относительно местоположения его пакета и имени файла - иными словами, если результирующий объект пути сохраняет участок ...com/our_company/javaFXViewCode.fxml, тогда его все еще очень удобно для нам нужно использовать объект NIO Path.

Большая часть этой информации фактически используется для отладки, поэтому для меня не будет невозможным модифицировать наш код, чтобы избежать использования путей в данном конкретном экземпляре и вместо этого использовать URI или просто строки, но это будет связано с связью переохлаждение для методов, которые уже удобно предоставляют объект nio.Path.

Я начал копать в the file system provider API и столкнулся с большей сложностью, чем я хочу иметь для такой маленькой вещи. Есть ли простой способ конвертировать из предоставленного URI класса-загрузчика в объект пути, соответствующий понятному обходному пути в случае URI, указывающий на файл без jar, а не понятный для ОС, но все же полезный обход в случае, когда путь указывает на ресурс внутри банки (или, в этом случае, почтовый индекс или архив)?

Спасибо за любую помощь

ответ

1

Java, Path принадлежит к FileSystem. Файловая система реализуется с помощью FileSystemProvider.

Java поставляется с двумя поставщиками файловой системы: один для операционной системы (например, WindowsFileSystemProvider) и один для почтовых файлов (ZipFileSystemProvider). Они являются внутренними и к ним не следует обращаться напрямую.

Чтобы получить файл Path файлу внутри Jar-файла, вам необходимо создать (создать) файл FileSystem для содержимого файла Jar. Затем вы можете получить файл Path в файл в этой файловой системе.

Во-первых, вам нужно разобрать Jar URL, который лучше всего сделать с помощью JarURLConnection:

URL jarEntryURL = new URL("jar:file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar!/com/our_company/javaFXViewCode.fxml"); 
JarURLConnection jarEntryConn = (JarURLConnection) jarEntryURL.openConnection(); 
URL jarFileURL = jarEntryConn.getJarFileURL(); // file:/C:/Program%20Files%20(x86)/OurSoftware/OurJar_x86_1.0.68.220.jar 
String entryName = jarEntryConn.getEntryName(); // com/our_company/javaFXViewCode.fxml 

После того, как у вас есть те, вы можете создать FileSystem и получить Path к jar'd файл. Помните, что FileSystem является открытым ресурсом и его необходимо закрыть, когда вы закончите с этим:

try (FileSystem jarFileSystem = FileSystems.newFileSystem(jarPath, null)) { 
    Path entryPath = jarFileSystem.getPath(entryName); 
    System.out.println("entryPath: " + entryPath); // com/our_company/javaFXViewCode.fxml 
    System.out.println("parent: " + entryPath.getParent()); // com/our_company 
}