我是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,但我怀疑这是最好的做法。
有什么想法吗?
答案 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();
}
}
}