Java: JSON als Konfigurationsdatei / properties.ini Alternative

Posted: Januar 18th, 2014 | Filed under: Java, Programmieren, Software, Tutorials | Tags: , , , , , , | No Comments »

imageIn meiner langjährigen Programmiererfahrung hatte ich schon öfters die Ehre mit sogenannten .ini- bzw. Property-Dateien zu arbeiten. Ich muss sagen, wirklich zufrieden war ich damit nie. Oft gab es Probleme mit der Identifikation von boolean Werten. Auch das behandeln von Listen in der jeweiligen Property-Datei war stets ein Sonderfall und handelte mir manchmal Schwierigkeiten ein. Ich glaube nicht mal das meine Abneigung an den prinzipiellen Aufbau und Grundgedanken einer .ini-Dateie gerichtet ist, vielmehr stören mich die mangelhaften Implementierungen der jeweiligen Programmiersprachen.

In folgendem Artikel möchte ich euch meine Implementierung einer Konfigurationsdatei auf Basis von JSON vorstellen. Diese verwendet die Bibliothek GSON und wird für folgende Implementierung benötigt. Wie ihr die Bibliothek in euer Projekt einbinden könnt erfahrt ihr hier nachlasen.

Die Klasse Config.java verwendet den Singleton-Mechanismus. Vorteil: Ihr müsst die Konfigurationsdatei nur einmal laden und erhält im Anschluss darauf Zugriff auf die jeweiligen Attribute innerhalb jeder anderen Klasse in eurer Applikation.

Config.java

package de.roth.json.config;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Config {

    // Hier schreibst du deine Attribute hin
    public String TITLE;
    public int WIDTH;
    public int HEIGHT;
    public double RATIO;
    public ArrayList<String> NAMES;

    public Config() {
        // Hier die Standardwerte der Attribute, falls diese
        // nicht in der Konfigurationsdatei
vorhanden sind. 
          
this.TITLE = "Titel der Anwendung";
        this.WIDTH = 800;
        this.HEIGHT = 600;
        this.RATIO = 0.6;
        this.NAMES = new ArrayList<String>();
        this.NAMES.add("Peter");
        this.NAMES.add("Paul");
    }

    // DON'T TOUCH THE FOLLOWING CODE
    private static Config instance;

    public static Config getInstance() {
        if (instance == null) {
            instance = fromDefaults();
        }
        return instance;
    }

    public static void load(File file) {
        instance = fromFile(file);

        // no config file found
        if (instance == null) {
            instance = fromDefaults();
        }
    }

    public static void load(String file) {
        load(new File(file));
    }

    private static Config fromDefaults() {
        Config config = new Config();
        return config;
    }

    public void toFile(String file) {
        toFile(new File(file));
    }

    public void toFile(File file) {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String jsonConfig = gson.toJson(this);
        FileWriter writer;
        try {
            writer = new FileWriter(file);
            writer.write(jsonConfig);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static Config fromFile(File configFile) {
        try {
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(configFile)));
            return gson.fromJson(reader, Config.class);
        } catch (FileNotFoundException e) {
            return null;
        }
    }

    @Override
    public String toString() {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        return gson.toJson(this);
    }
}

Die Verwendung dieser Klasse ist sehr einfach. Schaut selbst:

Test.java

package de.roth.json.config;

public class Test {

    public static void main(String[] args) {
        // Konfigurationsdatei laden, falls vorhanden.
        // Ansonsten werden die Werte im Konstruktor verwendet
        Config.load("config.json");

        // Zugriff auf Attribut
        Config.getInstance().TITLE = "Neuer Titel";
        Config.getInstance().RATIO = 0.4;
        for (String s : Config.getInstance().NAMES) {
            System.out.println(s);
        }

        // Speichern der Konfigurationsdatei
        Config.getInstance().toFile("config.json");
    }
}

Da in unserem Beispiel noch keine Konfigurationsdatei vorhanden war ergibt sich nach dem ändern und sichern der Konfiguration folgende JSON-Datei.

{
  "TITLE": "Neuer Titel",
  "WIDTH": 800,
  "HEIGHT": 600,
  "RATIO": 0.4,
  "NAMES": [
    "Peter",
    "Paul"
  ]
}

Mit Hilfe dieser Implementierung und GSON ist es natürlich auch möglich vollständige Objekte als Konfigurationsattribut abzulegen. GSON löst automatisch jedes Objekt in primitive Datenstrukturen auf und speichert es im Anschluss darauf als JSON-Objekt in der Konfigurationsdatei ab.

GitHub

Den Quellcode zu dem Projekt könnt ihr euch auch auf GitHub ansehen:

https://github.com/frankred/json-config-file

Download

Das ganze Beispiel könnt ihr euch zusätzlich hier als vollständiges Eclipse-Projekt herunterladen.


Gastbeitrag: C++ Text in Datei schreiben

Posted: Januar 29th, 2013 | Filed under: Programmieren, Tutorials | Tags: , , , , , , , | No Comments »

Immer wieder lese ich in Foren, dass Leute Probleme haben Text mit C++ in eine Datei zu schreiben. Wie man das ganz einfach mit der Standard Input and Output Library (stdio.h) realisieren kann, mag ich kurz in diesem Beitrag erklären.

/* Text in Datei schreiben */
#include <stdio.h>

int main () {
    // Zeiger auf den Typ FILE
    FILE* pDatei;

    // Die Datei ZuOeffnendeDatei.txt im Modus "w" öffnen.
    // Um Daten in eine Datei zu schreiben gibt es verschiedene Modi:
    //    w: Neue Datei zum schreiben erzeugen. Falls diese bereits existiert, wird sie überschrieben.
    //    a: Öffnet eine Datei zum schreiben. Falls diese bereits existiert, wird der Inhalt
    //       an den bereits bestehenden Inhalt angehängt.
    // Falls man neben den Schreiboperationen auch Inhalte aus der Datei auslesen möchte,
    // kann man statt w einfach w+ und statt a, a+ verwenden.
    pDatei = fopen("ZuOeffnendeDatei.txt","w");

    // Prüfen ob die Datei geöffnet werden konnte
    if (pDatei != NULL) {

        // Ausgabe in Datei leiten
        fprintf(pDatei, "Hallo blog.mynotiz.de Leser!");

    }

    // Wichtig, die Datei wieder schließen!
    fclose(pDatei);

    // Programmende
    return 0;
}

Ich hoffe, ich konnte dem ein oder anderen damit behilflich sein. 😉

Markus Mangei


Java Text in eine Datei schreiben

Posted: April 16th, 2009 | Filed under: Programmieren | Tags: , , , , , , , , , , | 14 Comments »

Heute möchte ich euch zeigen wie man mittels Java einfach man einen Text in eine Datei schreiben kann. Das ganze wird über den FileWriter realisiert. Dieser kann verschieden genutzt werden. Zum einen ist es möglich eine vorhandene Datei zu überschreiben, zum anderen kann ein Text an eine bereits bestehende Datei angehängt werden. Wie das funktioniert zeige ich euch im Quelltext.

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class FileWriterExample {
  
  FileWriter writer;
  File file;
  
  public void schreiben(){
    // File anlegen
     file = new File("FileWriterTest.txt");
     try {
       // new FileWriter(file ,true) - falls die Datei bereits existiert
       // werden die Bytes an das Ende der Datei geschrieben
       
       // new FileWriter(file) - falls die Datei bereits existiert
       // wird diese überschrieben
       writer = new FileWriter(file ,true);
       
       // Text wird in den Stream geschrieben
       writer.write("Hallo Wie gehts?");
       
       // Platformunabhängiger Zeilenumbruch wird in den Stream geschrieben
       writer.write(System.getProperty("line.separator"));

       // Text wird in den Stream geschrieben       
       writer.write("Danke mir gehts gut!");
       
       
       // Schreibt den Stream in die Datei
       // Sollte immer am Ende ausgeführt werden, sodass der Stream 
       // leer ist und alles in der Datei steht.
       writer.flush();
       
       // Schließt den Stream
       writer.close();
    catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    FileWriterExample fileWriterExample = new FileWriterExample();
    fileWriterExample.schreiben();
  }
}

Hier könnt ihr euch den Quelltext (FileWriterExample.java) herunterladen.