如何访问 OSGi 包内的文件?

发布于 2024-11-17 02:56:09 字数 491 浏览 5 评论 0 原文

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

我尝试使用 context.getBundle().getResource("/myfile") (其中 context 的类型为 org.osgi.framework.BundleContext),它返回 URI bundle: //6.0:0/myfile。 但此 URI 无法使用 File(URI uri) 构造函数转换为文件实例,因为它具有“bundle”方案。

人们可以尝试构建一条到达该位置的路径,了解工作目录并利用我的包的bundleId,但我怀疑这是最佳实践。

有什么想法吗?

I am new to OSGi and created an OSGi-bundle which I run in the Apache Felix OSGi-container.
There is a file resource contained in the bundle, which I need to pass to a method as a java.io.File. To instantiate a File-object, either an URI in the "file"-scheme or the path as string is necessary. How do I retrieve any of those in a clean way?

I tried using the
context.getBundle().getResource("/myfile") (where context is of type org.osgi.framework.BundleContext) which returns the URI bundle://6.0:0/myfile.
But this URI can't be converted to a File-instance using the File(URI uri) constructor since it has the "bundle"-scheme.

One could try to construct a path to the location knowing the working directory and exploiting the bundleId of my bundle, but I doubt this is the best practice.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

欢烬 2024-11-24 02:56:09

由于该文件位于您的包内,因此您无法使用标准的文件来访问它。您从 URL rel="noreferrer">Bundle.getResource() 是获取这些资源的正确方法,因为 OSGi API 也适用于没有实际文件系统的系统。我总是尝试坚持使用 OSGi API,而不是使用特定于框架的解决方案。

因此,如果您可以控制该方法,我会更新它以采用 URL,甚至可能是 InputStream (因为您可能只想从中读取)。为了方便起见,您始终可以提供一个确实接受文件的辅助方法。

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

Since the file is inside your bundle, there is no way for you to get to it using a standard File. The URL you get from Bundle.getResource() is the correct way to get to these resources, since the OSGi APIs are intended to also work on systems without an actual file system. I would always try to stick to the OSGi API instead of using framework-specific solutions.

So, if you have control over the method, I would update it to take a URL, or maybe even an InputStream (since you probably just want to read from it). For convenience, you can always provide a helper method that does take a File.

If you don't have control over the method, you will have to write some helper method that takes the URL, streams it out to a file (for instance, File.createTempFile() will probably do the trick.

溺渁∝ 2024-11-24 02:56:09

也许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)
希望这对您有帮助。

Maybe the API is confusable, but You can access a file inside an OSGI bundle like this:

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 will find the resource through the whole OSGI container just like OSGI classloader theory.
getEntry will find the resource from local bundle. and the return url could be convert to file but inputStream.
Here is a question same with this: No access to Bundle Resource/File (OSGi)
Hope this helping you.

南街女流氓 2024-11-24 02:56:09

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

What I use is getClassLoader().getResourceAsStream():

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

This way the file will be loaded from your resource dir. FileName should contain the path after "src/main/resources".

Full example here:

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();
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文