# Property-File lesen und schreiben



## Camino (15. Mrz 2011)

Hallo,

ich habe eine Swinganwendung, die in einem ausführbaren JAR liegen wird. Ich hab im Build-Path unter /resources/properties/ eine Propertiesdatei, welche so eingelesen wird:


```
...
	String propFile = "/resources/properties/user.conf";

	Properties prop = new Properties();
		
	try {
		InputStream instream = this.getClass().getResourceAsStream( propFile );
    		prop.load( instream );
    	} catch ( IOException ex ) {
    		ex.printStackTrace();
        }
...
```

Das klappt soweit auch prima. Ich kann die Properties einlesen und in meiner Anwendung auf die Werte zugreifen.

Wenn ich nun aber die Properties ändern möchte und wieder in der Datei abspeichern will, bekomme ich eine FileNotFoundException (No such file or directory), obwohl die Datei in diesem Verzeichnis liegt. Schreiben versuche ich so (hab ich nach Recherche im Internet so gefunden):


```
...
    	URL url =
    		this.getClass().getResource( propFile );
 
        if (url == null)
            return;
 
        File file = new File( url.getFile() );
 
        try {
            BufferedOutputStream bos =
                new BufferedOutputStream(new FileOutputStream( file ));
            if (bos == null)
                throw new IOException( "bos was null" );
                
            prop.store( bos, "Configuration" );
            
 
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

...
```

Kann mir jemand verraten, was ich falsch mache und einen Tipp geben, wie ich die Werte wieder in der Property-Datei abspeichern kann? Ich hatte irgendwo gelesen, dass es evtl. nicht möglich ist, so eine Property-Datei wieder in ein JAR zu schreiben/speichern. Aber irgendeine Möglichkeit muss es doch geben...

Viele Grüsse
Camino


----------



## Michael... (15. Mrz 2011)

In einem jar liegen keine Dateien im eigentlichen Sinn.
Einträge in einem jar können aus dem Programm heraus nicht geändert werden.
==> die Property Dateien nicht mit ins Java Archiv stecken.


----------



## Camino (16. Mrz 2011)

Michael... hat gesagt.:


> In einem jar liegen keine Dateien im eigentlichen Sinn.


Hmm, seltsam. Ich dachte immer, in einem JAR-File sind mehrere Dateien reingepackt. Wenn ich das mit dem Archivmanager öffne, sehe ich jedenfalls mehrere Dateien (z.B. class-Dateien, oder auch meine Bilder, die ich als Resource da drin hab) sowie eine Ordnerstruktur.



> Einträge in einem jar können aus dem Programm heraus nicht geändert werden.
> ==> die Property Dateien nicht mit ins Java Archiv stecken.


OK, werde ich mal versuchen und mich dann wieder melden...

Grüsse
Camino


----------



## Michael... (16. Mrz 2011)

Wie Du Du schon sagst, die Dateien werden da reingepackt --> stecken also komprimiert innerhalb einer Datei und sind somit Einträge bzw. Bestandteil einer Datei.


----------



## Dit_ (16. Mrz 2011)

Speichere doch einfach die Einstellungen in der Registry. So wird keine Datei gebraucht.
Problemloses lesen und schreiben.


----------



## Michael... (16. Mrz 2011)

Dit_ hat gesagt.:


> Problemloses lesen und schreiben.


Wir haben hier ein paar Applikationen laufen, mit denen ich Dir das Gegenteil beweisen kann ;-)
Aber für kleinere Applikationen die nur auf wenigen Clients laufen trifft das sicherlich zu bzw. eventuelle Probleme wären schnell zu beheben.

Ich bevorzuge aber weiterhin ein Property-File im "Installations"verzeichnis.


----------



## Camino (16. Mrz 2011)

Michael... hat gesagt.:


> Wie Du Du schon sagst, die Dateien werden da reingepackt --> stecken also komprimiert innerhalb einer Datei und sind somit Einträge bzw. Bestandteil einer Datei.



OK, danke. Wieder was dazugelernt...
Das mit der Properties-Datei ausserhalb des JARs lesen und schreiben klappt jetzt auch. Ich werde das auch lieber so machen, anstatt die Lösung mit der Registry, da somit auch die User die Möglichkeit haben, später die Daten per Hand in dem Textfile zu ändern.

Grüsse und Danke
Camino


----------



## Dit_ (16. Mrz 2011)

Michael... hat gesagt.:


> Wir haben hier ein paar Applikationen laufen, mit denen ich Dir das Gegenteil beweisen kann ;-)


:rtfm: kannst du mal bitte genauer erklären was da schief gehen kann? damit ich ggf meine Anwendung umcode 

P.S. falls man die Anwendung installiert dann ist die Datei am besten geeignet, ist schon richtig, da hat man alles an einem Ort (leichtere Deinstallation usw.)

würde aber gern die Nachteile der Registry wissen 

danke schon mal


----------



## Camino (16. Mrz 2011)

Gibt es eigentlich die Möglichkeit, eine Properties-Datei nach eigenen Wünschen zu gestalten? Also, die Einträge sortieren und gruppieren und mit Kommentaren und Leerzeilen versehen. Oder müsste ich dann "per Hand" eine Textdatei anlegen?


----------



## Dit_ (16. Mrz 2011)

zB so:


```
#kommentar
#omg windowTitle in config datei?
window.title = Mein Fenster
window.width = 550
```


----------



## Camino (16. Mrz 2011)

Ähm, ich meinte natürlich beim Abspeichern der Properties-Datei. Per Hand anlegen kann ich die Gestaltung und Struktur ja auch, aber beim Abspeichern geht das wohl wieder verloren. Es wird nur der Titel, ein Timestamp und die Key/Value-Einträge in die Datei reingeschrieben.


----------



## Gast2 (16. Mrz 2011)

Ini4j kannst du dafür verwenden. Da kannst du normale ini Dateien verwalten, d.h. gruppen anlegen und zugehörige key-value-paare. Die Reihenfolge bleibt da auch bestehen 
[ini4j] - Java API for handling Windows ini file format


----------



## Gastredner (16. Mrz 2011)

Camino hat gesagt.:


> Gibt es eigentlich die Möglichkeit, eine Properties-Datei nach eigenen Wünschen zu gestalten? Also, die Einträge sortieren und gruppieren und mit Kommentaren und Leerzeilen versehen. Oder müsste ich dann "per Hand" eine Textdatei anlegen?


ini4j sollte das können.
Einstellungsdateien würde ich auch eher in das Home-Verzeichnis des Benutzers legen bzw. an den Ort, auf den die System-Property user.home verweist. Bei manchen Betriebssystemen (Windows 7 z. B.) kann es sonst vorkommen, dass ein Benutzer Einstellungen des Programms nicht ändern kann, weil er keine Schreibrechte auf den Programmordner besitzt (wenn das Programm z. B. im Programme-Ordner von Windows landet und der Benutzer keine Admin-Rechte hat bzw. das Programm nicht mit diesen ausgeführt wird).


----------



## Dit_ (16. Mrz 2011)

heutzutage braucht man für jede kleinigkeit extra API... :shock:


----------



## bananenkasper (17. Mrz 2011)

Früher hat man jede Kleinigkeit selbst programmiert


----------



## Camino (17. Mrz 2011)

Gastredner hat gesagt.:


> ini4j sollte das können.
> Einstellungsdateien würde ich auch eher in das Home-Verzeichnis des Benutzers legen bzw. an den Ort, auf den die System-Property user.home verweist. Bei manchen Betriebssystemen (Windows 7 z. B.) kann es sonst vorkommen, dass ein Benutzer Einstellungen des Programms nicht ändern kann, weil er keine Schreibrechte auf den Programmordner besitzt (wenn das Programm z. B. im Programme-Ordner von Windows landet und der Benutzer keine Admin-Rechte hat bzw. das Programm nicht mit diesen ausgeführt wird).


OK, daran hab ich ja noch garnicht gedacht. Aber eigentlich wäre es mir lieber, wenn diese Property-Datei direkt auch beim Programm liegt. Na ja, muss ich nochmal drüber nachdenken. Im Moment soll das Programm eigentlich unter Linux laufen, aber man weiss ja nie...

Und wegen dem ini4j: eigentlich wäre es mir ja lieber, so viel wie möglich aus Java direkt zu benutzen und weniger auf externe API. Mal schauen, vielleicht programmier ich mir ja auch selbst was zusammen...

Danke für die Infos
Camino


----------



## nrg (17. Mrz 2011)

Camino hat gesagt.:


> Und wegen dem ini4j: eigentlich wäre es mir ja lieber, so viel wie möglich aus Java direkt zu benutzen und weniger auf externe API. Mal schauen, vielleicht programmier ich mir ja auch selbst was zusammen...



ich würde mich da fragen, was zuerst da ist.

wenn du intern konfiguration speichern willst, würde ich eine properties-datei nehmen. das aussehen und der aufbau interessiert da keinen und du kannst bequem die konfiguration auslesen.

wenn du die konfiguration des programmes vorher vornehmen möchstest, würde ich eher zu einer ini raten, weil das einfach imho deutlich übersichtlicher und schöner ist.

für größere sachen sollte man ne db nehmen.


----------



## Camino (17. Mrz 2011)

nrg hat gesagt.:


> ich würde mich da fragen, was zuerst da ist.
> 
> wenn du intern konfiguration speichern willst, würde ich eine properties-datei nehmen. das aussehen und der aufbau interessiert da keinen und du kannst bequem die konfiguration auslesen.
> 
> ...



Ja, muss ich mir nochmal durch den Kopf gehen lassen, ob es wirklich notwendig und gewünscht ist, dass die späteren User die Daten evtl. auch per Hand in der Datei ändern sollen können, oder ob die User diese Konfigurationsdatei nur über die Anwendung ändern sollen. Je nachdem werde ich dann Properties-Datei oder ini-File nehmen.

Ist eh eine grössere Anwendung, bei der schon eine Datenbank zum Einsatz kommt. Nur habe ich jetzt zwei verschiedene Konfigurationsmöglichkeiten: einmal global, die für alle User gelten. Das hab ich in der Datenbank gespeichert. Und dann sollen aber auch noch die jeweiligen User für sich (lokal) Konfigurationen vornehmen können, welche in einer Konfigurationsdatei auf der jeweiligen Arbeitsstation gespeichert werden sollen.

Camino


----------



## Gastredner (17. Mrz 2011)

Camino hat gesagt.:


> OK, daran hab ich ja noch garnicht gedacht. Aber eigentlich wäre es mir lieber, wenn diese Property-Datei direkt auch beim Programm liegt. Na ja, muss ich nochmal drüber nachdenken. Im Moment soll das Programm eigentlich unter Linux laufen, aber man weiss ja nie...


Solange das Problem nur an Stellen liegt, wo der Ausführende definitiv alle Rechte hat (z. B. im home-Verzeichnis), ist dies absolut kein Problem.



> Und wegen dem ini4j: eigentlich wäre es mir ja lieber, so viel wie möglich aus Java direkt zu benutzen und weniger auf externe API. Mal schauen, vielleicht programmier ich mir ja auch selbst was zusammen...


Anders ausgedrückt: du willst eine ausgereifte und vielfach erprobte kleine API, die genau bietet was du benötigst, ersetzen durch ein Eigenkonstrukt, welches mit einer guten Wahrscheinlichkeit weniger performant und durchdacht ist und zudem vermutlich Bugs enthalten wird?
Gut, wenn es darum geht, dass man es mal gerne aus Wissensdurst machen würde, ist das kein Problem. Aber ansonsten würde ich eher zur erprobten Bibliothek tendieren, damit hat man weniger Kopfschmerzen.


----------



## Dit_ (17. Mrz 2011)

Camino hat gesagt.:


> Ähm, ich meinte natürlich beim Abspeichern der Properties-Datei. Per Hand anlegen kann ich die Gestaltung und Struktur ja auch, aber beim Abspeichern geht das wohl wieder verloren. Es wird nur der Titel, ein Timestamp und die Key/Value-Einträge in die Datei reingeschrieben.



dafür brauchst du nur eine methode save() zu schreiben und bestimmt keine extra API mit dützend anderen Funktionalitäten, nur um diese eine Kleinigkeit zu erledigen.

_//Vorbereitung kann auch beim Laden der Einstellungen erfolgen_

Lese alte Datei Zeile für Zeile
Merke Kommentar 
	
	
	
	





```
line.startsWith("#")
```

Merke Schluessel der nach dem Kommentar kommt.
Lege kommentar in einer HashMap ab
_
//Einstellungen speichern_

Durchlaufe alle Schluessel 
	
	
	
	





```
for(String key : preferences.keys())
```

Gibt es einen Kommentar für key?
Wenn ja: hole Kommentar aus der map und schreibe in die Datei.
Schreibe danach 
	
	
	
	





```
key + '=' + preferences.get(key, "irgendeinDefaultWert")
```
 als nächste Zeile
Fertig.

Wenn du eine Klasse hast, die nur für das Laden/Speichern der Einstellungen zuständig ist, wird diese nun um max 20 Zeilen größer.


----------



## Camino (17. Mrz 2011)

Gastredner hat gesagt.:


> Solange das Problem nur an Stellen liegt, wo der Ausführende definitiv alle Rechte hat (z. B. im home-Verzeichnis), ist dies absolut kein Problem.


OK.



> Anders ausgedrückt: du willst eine ausgereifte und vielfach erprobte kleine API, die genau bietet was du benötigst, ersetzen durch ein Eigenkonstrukt, welches mit einer guten Wahrscheinlichkeit weniger performant und durchdacht ist und zudem vermutlich Bugs enthalten wird?


Hehe, genauso hab ich mir das vorgestellt... ;-)



> Gut, wenn es darum geht, dass man es mal gerne aus Wissensdurst machen würde, ist das kein Problem. Aber ansonsten würde ich eher zur erprobten Bibliothek tendieren, damit hat man weniger Kopfschmerzen.


Ja, das Dazulernen ist bei mir (auch) ein wichtiger Faktor. Aber mir geht es oft so, dass ich vor einem kleinen Problem stehe und eine Lösung suche, und mir dann eine solche externe API oftmals zu überdimensioniert für mein Problemchen vorkommt. Na ja, ich schaue nochmal, ob ich mit den normalen Properties-Dateien auskomme oder ob ich ein INI-File brauche. Dann schau ich mir das nochmal genauer an.

Danke
Camino


----------

