使用 Scala 读取类路径下的属性文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15110315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 05:00:47  来源:igfitidea点击:

Read property file under classpath using scala

scalaclasspath

提问by zjffdu

I am trying to read a property file from classpath using scala. But it looks like it won't work, it is different from java. The following 2 code snippet, one is java (working), another is scala (not working). I don't understand what is the difference.

我正在尝试使用 Scala 从类路径读取属性文件。不过貌似不行,和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)

采纳答案by suls

I am guessing that your BufferedReaderis a java.io.BufferedReader

我猜你BufferedReader是一个java.io.BufferedReader

In that case you could simply do the following:

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

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

However, this leaves the question open as to what you are planning to do with the readerafterwards. scala.io.Sourcealready has some useful methods that might make lots of your code superfluous .. see ScalaDoc

然而,这留下了一个问题,即您计划对reader之后做什么。scala.io.Source已经有一些有用的方法可能会使您的许多代码变得多余……请参阅 ScalaDoc

回答by Roman Nikitchenko

This code finally worked for me:

这段代码终于对我有用了:

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())
}

And now you have plain old java.util.Properties to handle what my legacy code actually needed to receive.

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

回答by Chirlo

For reading a Properties file i'd recommend to use java.util.ResourceBundle.getBundle("conf/fp"), it makes life a little easier.

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

回答by iwein

The NullPointerException you are seeing is caused by a bug in the underlying Java code. It couldbe caused by a mistyped file name.

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

Sometimes you get this error also if you're trying to load the resource with the wrong classloader.

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

  1. Check the resource url carefully against your classpath.
  2. Try Source.fromInputStream(getClass.getResourceAsStream(...))
  3. Try Source.fromInputStream(getClass.getClassLoader.getResourceAsStream())
  4. Maybe you are using other classloaders you can try?
  1. 根据您的类路径仔细检查资源 url。
  2. 尝试 Source.fromInputStream(getClass.getResourceAsStream(...))
  3. 尝试 Source.fromInputStream(getClass.getClassLoader.getResourceAsStream())
  4. 也许您正在使用其他可以尝试的类加载器?

The same story goes for Source.fromUrl(...)

同样的故事 Source.fromUrl(...)

If you're trying to load configuration files and you control their format, you should have a look at Typesafe's Configutility.

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

回答by harschware

The Null Pointer Exception you are getting is from getResourceAsStream returning null. The following junit.scala snippet shows how there is a difference in class vs classloader. see What is the difference between Class.getResource() and ClassLoader.getResource()?. Here I assume fileNameis the name of a file residing in the class path, but not a file next to the class running the test.

您得到的空指针异常来自 getResourceAsStream 返回空值。以下 junit.scala 片段显示了类与类加载器之间的区别。请参阅Class.getResource() 和 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)

回答by Francisco López-Sancho

My prefered solution is with com.typesafe.scala-logging. I did put an application.conf file in main\resources folder, with content like:

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

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

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

and the to use it in a class, first load the config factory from typesafe and then just use it.

并在类中使用它,首先从类型安全加载配置工厂,然后使用它。

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

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

Hope it helps!

希望能帮助到你!

Ps. I bet that every file on resources with .conf as extension will be read.

附言。我敢打赌,将读取扩展名为 .conf 的资源上的每个文件。