我正在尝试编写和读取文件。任何人都可以解释是什么让事情变得不同。
我从属性文件中获取属性,并且我有在我的应用程序中使用的不同文件的路径。
问题是我的应用程序的行为会在运行此代码时发生变化。例如,如果我通过maven编译代码并运行JUnit测试,则不会获取资源文件夹中的test.properties,我必须将它放在项目的根目录中才能工作。其次,适用于某些文件的代码,我想从一个文件夹或者jar中复制,是两组不同的代码。因此,为此操作执行JUnit测试方法是没用的,因为我可以使用不同的方式使其在测试用例中工作,并使其在另一个jar中工作。
我的test.properties有:
cssFileLocation =src/main/resources/all.css
我的production.properties有(可以将资源文件夹中的文件移动到Jar的根目录):
cssFileLocation=all.css
我的代码是以下方法,它应该将css文件移动到/static/all.css
下的外部目录中:
public static void copyCSS(String newCSSTargetLocation, String cssFileLocation) {
File source = null;
String line = "";
String cssString = null;
source = new File(cssFileLocation);
File dest = new File(newCSSTargetLocation + "/static/all.css");
logger.debug("Absoulte path of css file : " + source.getAbsolutePath());
/**
* The Block below works when executing the jar
*/
InputStream input;
input = GeoUtils.class.getClassLoader().getResourceAsStream(cssFileLocation);
StringBuilder sb = new StringBuilder("");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input));) {
line = "";
if (null == reader) {
logger.debug("reader is null");
}
while ((line = reader.readLine()) != null) {
sb = sb.append(line);
sb = sb.append("\n");
}
cssString = new String(sb);
} catch (IOException | NullPointerException ex) {
logger.error("Exception in Buffered reader writer ....");
ex.printStackTrace();
}
/**
* This Block works when doing compile and tests are run through
* Surefire
*/
try {
cssString = FileUtils.readFileToString(source, "UTF-8");
} catch (IOException ex) {
logger.error("Exception occured when reading through new File " + cssFileLocation);
ex.printStackTrace();
}
if (null == dest) {
logger.debug("destination file is a null file Cannot proceed to create all.css in " + newCSSTargetLocation);
} else {
logger.debug(" dest not null " + dest.getAbsolutePath());
try {
FileUtils.writeStringToFile(dest, cssString, "UTF-8");
logger.debug(" all.css created to new location Through File Utils >>" + dest.getAbsolutePath());
} catch (IOException ex) {
logger.error("Exception occured when writing to " + dest.getAbsolutePath());
ex.printStackTrace();
}
}
}
运行在编译期间调用此方法的测试方法时出现的错误(mvn clean install)
ERROR [main] (GeoUtils.java:673) - Exception in Buffered reader writer ....
java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:78)
at java.io.InputStreamReader.<init>(InputStreamReader.java:72)
at com.sarm.lonelyplanet.common.GeoUtils.copyCSS(GeoUtils.java:658)
at com.sarm.lonelyplanet.common.GeoUtilsTest.testCopyCSS(GeoUtilsTest.java:207)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
答案 0 :(得分:2)
以下是Maven的工作原理。
编译项目时,会将src/main/resources
的内容复制到target/classes
。运行单元测试时,target/classes
是类路径的一部分。它也是您放入生产应用程序中的类路径中的jar的内容。
因此,无论您是在执行测试还是在生产中运行,项目中all.css
中的文件src/main/resources
都会在类路径的根目录中结束。所以你需要加载这个文件
SomeClass.getClassLoader().getResourceAsStream("all.css");
相同的代码和相同的路径在您的测试和生产中都能正常工作。您不应该使用文件IO来读取src / main / resources中的文件。这些不是真正的文件。它们是打算由类加载器加载的资源。