进行Eclipse插件开发或者RCP开发的时候,常常遇到这样的需求:程序员准备了几个文件打在jar包里,在程序运行的时候由用户的操作触发,要读jar包里的这几个文件,显示内容在界面上,或者直接复制文件到用户的目录中。这里提供两种直截了当的方法来实现这一目的。
第一,使用OSGi自带的utility class / methods,例子中的com.company.example是bundle (或者plugin) 的id,要读的文件是这个bundle中 resources文件夹中的 backup.txt 文件。
Bundle bundle = Platform.getBundle("com.company.example"); URL fileURL = bundle.getEntry("resources/backup.txt"); File file = null; try { file = new File(FileLocator.resolve(fileURL).toURI()); } catch (URISyntaxException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
URL url; try { url = new URL("platform:/plugin/com.company.example/resources/backup.txt"); InputStream inputStream = url.openConnection().getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } in.close(); } catch (IOException e) { e.printStackTrace(); }
如果要拷贝文件到Eclipse RCP项目 (生成IFile) 的话,直接用org.eclipse.core.resources.IFile的
void create(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException
方法以及利用URL.openConnection()得到的 InputStream来生成。
第二种方法比第一种有几个优点:
1、不需要import org.eclipse.core.runtime,org.osgi.framework包,
或者depend on org.eclipse.core.runtime这个bundle
2、org.osgi.framework.Bundle的 getEntry(String path) 方法对于不同的文件系统协议有不同的处理方式,比如file:/, jar:/, zip:/ 都有细微差别
从下面粘贴的官方文档中模棱两可的解释就可见一斑,一不小心就可能出错,而且在不同环境中可能会出现意想不到的bug (比如在Eclipse环境下工作的好好的,各个bundle都打成jar包以后可能就会路径报错)
java.net.URL getEntry(java.lang.String path)
The specified path is always relative to the root of this bundle and may begin with "/". A path value of "/" indicates the root of this bundle.
Note: Jar and zip files are not required to include directory entries. URLs to directory entries will not be returned if the bundle contents do not contain directory entries.
path
- The path name of the entry.
null
if no entry could be found or if the caller does not have the appropriate
AdminPermission[this,RESOURCE]
and the Java Runtime Environment supports permissions.
java.lang.IllegalStateException
- If this bundle has been uninstalled.