2013-02-27 11 views
7

Próbuję odczytać plik właściwości ze ścieżki klasy przy użyciu scala. Wygląda jednak na to, że nie będzie działać, różni się od języka Java. Poniższy 2 fragment kodu, jeden to java (działający), drugi to scala (nie działa). Nie rozumiem, jaka jest różnica.Odczytaj plik właściwości pod ścieżką klasy przy użyciu 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) 
+0

Dlaczego nie używasz [Config] (https://github.com/typesafehub/config)? –

+3

Mam rozwiązanie, powinienem użyć absolutnej ścieżki tutaj "/conf/fp.properties", ale wciąż nie jest jasne, dlaczego ścieżka względna działa w java, ale nie w scala – zjffdu

Odpowiedz

6

Domyślam się, że BufferedReader jest java.io.BufferedReader

W takim przypadku można po prostu wykonaj następujące czynności:

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

to jednak pozostawia kwestię otwartą, co planujesz później zrobić z reader. scala.io.Source ma już kilka użytecznych metod, które mogą sprawić, że wiele kodu będzie zbędnych. see ScalaDoc

+0

Co zrobić, jeśli plik właściwości znajduje się w pliku jar (np. W katalogu zasobów)? –

+0

[Od] (http://stackoverflow.com/questions/5285898/how-to-get-a-resource-within-scalatest-w-sbt): 'val source = Source.fromURL (getClass.getResource ("/conf/fp.properties "))' – suls

+0

To jest lepsze podejście –

2

Do odczytu pliku właściwości zalecam użycie java.util.ResourceBundle.getBundle("conf/fp"), ułatwia to życie.

0

Wykryty wyjątek NullPointerException jest spowodowany błędem w podstawowym kodzie Java. To może być spowodowane przez błędnie nazwaną nazwę pliku.

Czasami ten błąd pojawia się również wtedy, gdy próbujesz załadować zasób przy użyciu niewłaściwego programu ładującego klasy.

  1. Sprawdź adres zasobu ostrożnie w stosunku do swojej ścieżki klas.
  2. Spróbuj Source.fromInputStream(getClass.getResourceAsStream(...))
  3. Spróbuj Source.fromInputStream(getClass.getClassLoader.getResourceAsStream())
  4. Może używasz innych classloaders można spróbować?

Ta sama historia idzie Source.fromUrl(...)

Jeśli próbujesz załadować pliki konfiguracyjne i kontrolować ich format, należy spojrzeć na Config użyteczności Typesafe użytkownika.

0

Wyjątek zerowego wskaźnika, który otrzymujesz, pochodzi z metody getResourceAsStream, która zwraca wartość null. Poniższy fragment junit.scala pokazuje, w jaki sposób istnieje różnica między klasą a klasą ładującą. patrz What is the difference between Class.getResource() and ClassLoader.getResource()?. Tutaj zakładam, że fileName to nazwa pliku znajdującego się w ścieżce klasy, ale nie plik obok klasy prowadzącej test.

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

Ten kod wreszcie pracował dla mnie:

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

A teraz masz zwykły stary java.util.Properties do obsługi co mój starszy kod rzeczywiście potrzebne do odbioru.

0

Moje preferowane rozwiązanie to com.typesafe.scala-logging. I nie umieścić plik application.conf w głównym folderze \ Resources, z zawartością jak:

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

i używać go w klasie, najpierw załadować config z typesafe fabrykę, a potem po prostu go używać.

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

Nadzieję, że to pomaga!

Ps. Założę się, że każdy plik w zasobach z rozszerzeniem .conf zostanie odczytany.

Powiązane problemy