16

我是 OSGi 的新手,我创建了一个 OSGi 捆绑包,我在 Apache Felix OSGi 容器中运行它。捆绑包中包含一个文件资源,我需要将其作为java.io.File. 要实例化文件对象,“文件”方案中的 URI 或字符串形式的路径是必需的。如何以干净的方式检索其中的任何一个?

我尝试使用 返回 URI的context.getBundle().getResource("/myfile")(其中 context 是 type ) 。但是这个 URI 不能使用构造函数转换为 File-instance,因为它有“bundle”-scheme。org.osgi.framework.BundleContextbundle://6.0:0/myfileFile(URI uri)

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

有任何想法吗?

4

3 回答 3

16

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

因此,如果您可以控制该方法,我会将其更新为采用 a URL,甚至可能是 a InputStream(因为您可能只想从中读取)。为方便起见,您始终可以提供一个确实需要File.

如果您无法控制该方法,则必须编写一些辅助方法,将URL, 流式传输到文件中(例如,File.createTempFile()可能会成功。

于 2011-06-25T10:41:41.310 回答
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 可以转换为文件但 inputStream.
这是一个与此相同的问题:No access to Bundle Resource/File (OSGi) 希望这对您有所帮助。

于 2013-05-26T08:20:37.870 回答
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();
        }
    }
}
于 2015-05-29T14:31:53.997 回答