Подтвердить что ты не робот

Как получить доступ к файлу внутри пакета OSGi?

Я новичок в OSGi и создал пакет OSGi, который я запускаю в контейнере OSGi Apache Felix. В пакете содержится файл, который мне нужно передать методу java.io.File. Чтобы создать экземпляр Файлового объекта, необходим либо URI в "file" -схеме, либо путь как строка. Как получить любой из них в чистом виде?

Я попытался использовать context.getBundle().getResource("/myfile") (где context имеет тип org.osgi.framework.BundleContext), который возвращает URI bundle://6.0:0/myfile. Но этот URI не может быть преобразован в экземпляр File с помощью конструктора File(URI uri), так как он имеет схему "bundle".

Можно попытаться построить путь к местоположению, зная рабочий каталог и используя bundleId моего пакета, но я сомневаюсь, что это лучшая практика.

Любые идеи?

4b9b3361

Ответ 1

Поскольку файл находится внутри вашего пакета, вам не удастся добраться до него, используя стандартный File. URL вы получаете от Bundle.getResource() - это правильный способ добраться до этих ресурсов, поскольку API OSGi также должен работать системы без реальной файловой системы. Я всегда старался придерживаться API OSGi вместо использования решений, ориентированных на конкретную инфраструктуру.

Итак, если у вас есть контроль над методом, я бы обновил его, чтобы взять URL или, возможно, даже InputStream (так как вы, вероятно, просто хотите его прочитать). Для удобства вы всегда можете предоставить вспомогательный метод, который принимает File.

Если у вас нет контроля над методом, вам придется написать некоторый вспомогательный метод, который принимает URL, передает его в файл (например, File.createTempFile(), вероятно, сделает трюк.

Ответ 2

Возможно, API запутан, но вы можете получить доступ к файлу внутри пакета OSGI следующим образом:

URL url = context.getBundle().getResource("com/my/weager/impl/test.txt");

// The url maybe like this: bundle://2.0:2/com/my/weager/impl/test.txt
// But this url is not a real file path :(, you could't use it as a file.
// This url should be handled by the specific URLHandlersBundleStreamHandler, 
// you can look up details in BundleRevisionImpl.createURL(int port, String path)
System.out.println(url.toString());

BufferedReader br =new BufferedReader(new InputStreamReader(url.openConnection().getInputStream()));
while(br.ready()){
    System.out.println(br.readLine());
}
br.close();

getResource найдет ресурс через весь контейнер OSGI, как теория загрузки классов OSGI.
getEntry найдет ресурс из локального пакета. и возвращаемый url может быть преобразован в файл, но inputStream.
Вот вопрос с этим: Нет доступа к Bundle Resource/File (OSGi) Надеюсь, это поможет вам.

Ответ 3

Я использую getClassLoader(). getResourceAsStream():

InputStream inStream = new java.io.BufferedInputStream(this.getClass().getClassLoader().getResourceAsStream(fileName));

Таким образом, файл будет загружен из вашего ресурса. Имя_файла должно содержать путь после "src/main/resources".

Полный пример:

static public byte[] readFileAsBytes(Class c, String fileName) throws IOException {
    InputStream inStream = new java.io.BufferedInputStream(c.getClassLoader().getResourceAsStream(fileName));
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int nbytes = 0;
    byte[] buffer = new byte[100000];

    try {
        while ((nbytes = inStream.read(buffer)) != -1) {
            out.write(buffer, 0, nbytes);
        }
        return out.toByteArray();
    } finally {
        if (inStream != null) { 
            inStream.close();
        }
        if (out != null) {
            out.close();
        }
    }
}