Как получить доступ к файлу внутри пакета OSGi? - PullRequest
13 голосов
/ 25 июня 2011

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

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

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

Есть идеи?

Ответы [ 3 ]

12 голосов
/ 25 июня 2011

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

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

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

7 голосов
/ 26 мая 2013

Может быть, 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) Надеюсь, это поможет вам.

1 голос
/ 29 мая 2015

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

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

Таким образом, файл будет загружен из директории вашего ресурса.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();
        }
    }
}
...