使用scala读取classpath下的属性文件

时间:2013-02-27 10:57:29

标签: scala classpath

我正在尝试使用scala从classpath读取属性文件。但看起来它不会起作用,它与java不同。以下2个代码片段,一个是java(工作),另一个是scala(不工作)。我不明白有什么不同。

// working
BufferedReader reader = new BufferedReader(new InputStreamReader(
Test.class.getResourceAsStream("conf/fp.properties")));

// not working 
val reader = new BufferedReader(new InputStreamReader(
getClass.getResourceAsStream("conf/fp.properties")));

Exception in thread "main" java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:78)
at java.io.InputStreamReader.<init>(InputStreamReader.java:72)
at com.ebay.searchscience.searchmetrics.fp.conf.FPConf$.main(FPConf.scala:31)
at com.ebay.searchscience.searchmetrics.fp.conf.FPConf.main(FPConf.scala)

6 个答案:

答案 0 :(得分:6)

我猜你的BufferedReaderjava.io.BufferedReader

在这种情况下,您可以简单地执行以下操作:

import scala.io.Source.fromUrl
val reader = fromURL(getClass.getResource("conf/fp.properties")).bufferedReader()

但是,这样就可以解决您计划在事后reader做什么的问题。 scala.io.Source已经有一些有用的方法可能会使你的代码变得多余。see ScalaDoc

答案 1 :(得分:6)

这段代码最终对我有用:

import java.util.Properties
import scala.io.Source

// ... somewhere inside module.

var properties : Properties = null

val url = getClass.getResource("/my.properties")
if (url != null) {
    val source = Source.fromURL(url)

    properties = new Properties()
    properties.load(source.bufferedReader())
}

现在你有了普通的旧java.util.Properties来处理我的遗留代码实际需要接收的内容。

答案 2 :(得分:2)

为了阅读我建议使用java.util.ResourceBundle.getBundle("conf/fp")的属性文件,它会让生活变得更轻松。

答案 3 :(得分:0)

您看到的NullPointerException是由底层Java代码中的错误引起的。 可能是由错误输入的文件名引起的。

如果您尝试使用错误的类加载器加载资源,有时也会出现此错误。

  1. 仔细检查资源网址与您的类路径。
  2. 尝试Source.fromInputStream(getClass.getResourceAsStream(...))
  3. 尝试Source.fromInputStream(getClass.getClassLoader.getResourceAsStream())
  4. 也许您正在使用其他可以尝试的类加载器?
  5. 同样的故事适用于Source.fromUrl(...)

    如果您尝试加载配置文件并控制其格式,则应该查看Typesafe的Config实用程序。

答案 4 :(得分:0)

你得到的Null Pointer Exception来自getResourceAsStream,返回null。以下junit.scala片段显示了类与类加载器之间的区别。见What is the difference between Class.getResource() and ClassLoader.getResource()?。这里我假设fileName是驻留在类路径中的文件的名称,但不是运行测试的类旁边的文件。

assertTrue(getClass.getClassLoader().getResourceAsStream(fileName) != null)
assertTrue(getClass.getClassLoader().getResourceAsStream("/" + fileName) == null)
assertTrue(getClass.getResourceAsStream(fileName) == null)
assertTrue(getClass.getResourceAsStream("/" + fileName) != null)

答案 5 :(得分:0)

我首选的解决方案是使用com.typesafe.scala-logging。我确实在main \ resources文件夹中放了一个application.conf文件,内容如下:

services { mongo-db { retrieve = """http://xxxxxxxxxxxx""", base = """http://xxxxxx""" } }

并且要在类中使用它,首先从typesafe加载配置工厂,然后只使用它。

val conf = com.typesafe.config.ConfigFactory.load() conf.getString("services.mongo-db.base"))

希望它有所帮助!

聚苯乙烯。我敢打赌,将会读取.conf作为扩展名的资源上的每个文件。