如何访问OSGi包中的文件?

时间:2011-06-24 23:11:24

标签: osgi apache-felix file-access

我是OSGi的新手并创建了一个OSGi-bundle,我在Apache Felix OSGi-container中运行。 包中包含一个文件资源,我需要将其作为java.io.File传递给方法。要实例化File-object,需要“file”-scheme中的URI或字符串作为字符串。如何以干净的方式检索任何这些?

我尝试过使用 context.getBundle().getResource("/myfile")(其中上下文类型为org.osgi.framework.BundleContext),返回URI bundle://6.0:0/myfile。 但是这个URI无法使用File(URI uri)构造函数转换为File-instance,因为它具有“bundle”-scheme。

可以尝试构建一个知道工作目录的位置路径并利用我的bundle的bundleId,但我怀疑这是最好的做法。

有什么想法吗?

3 个答案:

答案 0 :(得分:12)

由于文件在您的捆绑包中,因此您无法使用标准File访问它。从Bundle.getResource()获得的URL是获取这些资源的正确方法,因为OSGi API也适用于没有实际文件系统的系统。我总是试图坚持使用OSGi API,而不是使用特定于框架的解决方案。

因此,如果您可以控制该方法,我会将其更新为URL,或者甚至是InputStream(因为您可能只想读取它)。为方便起见,您始终可以提供 获取File的帮助方法。

如果您无法控制该方法,则必须编写一些带有URL的辅助方法,将其流式传输到文件中(例如,File.createTempFile()可能会执行特技。

答案 1 :(得分:7)

也许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可以转换为file而不是inputStream 这是一个与此相同的问题:No access to Bundle Resource/File (OSGi) 希望这对你有所帮助。

答案 2 :(得分:1)

我使用的是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();
        }
    }
}