现象:在RCP程序中,以相对路径读文件遇到以下异常。但用绝对路径则没有问题。
try { FileInputStream fileStream = new FileInputStream("poc.xml"); } catch (FileNotFoundException e1) { e1.printStackTrace(); }
java.io.FileNotFoundException: poc.xml (The system cannot find the file specified) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.<init>(Unknown Source) at java.io.FileInputStream.<init>(Unknown Source) at LoadFile.execute(LoadFile.java:30) at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:293) at org.eclipse.core.commands.Command.executeWithChecks(Command.java:476) at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:508) at org.eclipse.ui.internal.handlers.HandlerService.executeCommand(HandlerService.java:169) at org.eclipse.ui.internal.handlers.SlaveHandlerService.executeCommand(SlaveHandlerService.java:241) at org.eclipse.ui.menus.CommandContributionItem.handleWidgetSelection(CommandContributionItem.java:829) at org.eclipse.ui.menus.CommandContributionItem.access$19(CommandContributionItem.java:815) at org.eclipse.ui.menus.CommandContributionItem$5.handleEvent(CommandContributionItem.java:805) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4165) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3754) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2696) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2660) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2494) at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:674) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:667) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at testsample.Application.start(Application.java:20) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) at org.eclipse.equinox.launcher.Main.main(Main.java:1386)
解决:
方法一:
Class.getClassLoader().getResource(name); //或者 Class().getClassLoader().getResourceAsStream(name);
方法二:
如果你必须用到File,那可以参考下面的代码,但前提是你已经为你的Project建立了Product
Bundle bundle = Platform.getProduct().getDefiningBundle(); URL fileURL = bundle.getEntry(path); File file = null; try { file = new File(FileLocator.resolve(fileURL).toURI()); } catch (URISyntaxException e1) { e1.printStackTrace(); return; } catch (IOException e1) { e1.printStackTrace(); return; }
参考转换中值:
path:data/testcase/
fileURL:bundleentry://30.fwk648734830/data/testcase/
FileLoactor.resove(fileURL):file:/D:/Project/autotester-I20110901/data/testcase/
file.path:D:\Project\autotester-I20110901\data\testcase
用getClass().openResourceAsSteam(path)和用bundle.getEntry(path)的path是不一样的,前者的当前路径是class/classDir(Project/conf/),后者的当前路径是project(Project/)。即,如果你的文件路径为是放在Project/config/a.xml,而config加入classpath中,那么方法一的要传入"a.xml",而方法二要传入“config/a.xml”。