Zeilen über bufferedReader einlesen und in Array zusammenfügen

Hallo,

ich habe folgendes Problem.
Ich lese über einen BufferedReader einen String ein der folgenden Aufbau hat.

Es existieren eine Vielzahl des durch “{” und “}” begrenzter Blöcke.
Anbei ein Auszug:
`
contactstatus {
contact_name=Held
modified_attributes=0
modified_host_attributes=0
modified_service_attributes=0
host_notification_period=24x7
service_notification_period=24x7
last_host_notification=1368003695
last_service_notification=1376907838
host_notifications_enabled=1
service_notifications_enabled=1
}

contactstatus {
contact_name=nagiosadmin
modified_attributes=0
modified_host_attributes=0
modified_service_attributes=0
host_notification_period=24x7
service_notification_period=24x7
last_host_notification=1368003695
last_service_notification=1376918688
host_notifications_enabled=1
service_notifications_enabled=1
}`
Ich möchte nun den zwischen den geschwungenen Klammern angeführten Text in ein Array schreiben.
Wie kann ich denn das machen, ohne die Zeilen mehrfach einlesen zu müssen?

Dank GGK

Welchen Regeln entspricht denn dieser eingelesene String? Sind zwischen den einzelenen Teilen immer Leerzeichen oder Zeilenumbrüche? Schau dir mal String.split an.

Andere Frage: Woher ließt du das Zeug ein? Und was hast du damit vor? Für mich sieht das eher aus als wolltest du irgendwie mit Properties arbeiten!?

Zuerst mal die Frage: Warum ein Array? Eine [JAPI]List[/JAPI] wäre doch besser geeignet?

Und als nächste Frage: Die Struktur Deiner Datei schreit doch gerade zu nach einem Objekt ContactStatus. Darüber hinaus sieht das verdächtig nach JSON-Syntax aus. Gibts da nicht schon fertige Frameworks für’s parsen?

Und damit sind wir auch schon bei der Lösung, die ich mir vorstellen könnte:

Wenn Du in deinem Stream auf das Wort “contactstatus” triffst erzeugst Du ein neues ContactStatus-Objekt Und befüllst dessen Felder so lange bis Du auf die schließende Klammer triffst. Dann legst Du dieses Objekt in eine Liste.

bye
TT

Hmm…ja…eine List wäre wohl wirklich die bessere Alternative…oder ein Vector…

Ich schreibe mir ein Programm, mit dem ich das Nagios status-File auslesen kann und dieses hat genau diese Form. Das ist kein Properties bzw. auch kein JSON.

Was meinst du damit…ein ContactStatus Objekt zu erzeugen?

Dank eGGK

Er meint damit, dass du eine Klasse hast die ContactStatus heißt und in der du Attribute hast für die Entsprechenden Felder…

Falls du nicht mit Split arbeiten willst könntest du auch den Teil außerhalb inkl. der geschweiften Klammern weglassen, dann hättest du das Format von Properties und könntest ggf. damit arbeiten: Klick

[QUOTE=GGK]Hmm…ja…eine List wäre wohl wirklich die bessere Alternative…oder ein Vector…[/QUOTE]Du kennst den Unterschied zwischen [JAPI]ArrayList[/JAPI] und [JAPI]Vector[/JAPI]?

[QUOTE=GGK;28438]Ich schreibe mir ein Programm, mit dem ich das Nagios status-File auslesen kann und dieses hat genau diese Form. Das ist kein Properties bzw. auch kein JSON.[/QUOTE]Bei letzterem wäre ich mir nicht so sicher…

[QUOTE=GGK;28438]Was meinst du damit…ein ContactStatus Objekt zu erzeugen?[/QUOTE]Genau das.
Schreibe eine Klasse ContactStatus und erzeuge Objekte von dieser.

bye
TT

wie könnte ich das denn mit split lösen?

[QUOTE=GGK]wie könnte ich das denn mit split lösen?[/QUOTE]Nein.
split() benötigt den kompletten String im Speicher. Je nach dem wie groß die Datei sein kann wäre das nicht ratsam. Außerdem müsstest Du dannach genau so über die Array-Elemente iterieren, wie über die Zeilen des (Buffered)Readers. Du hättest das eigentliche Problem, das Zerlegen des Eingabestromes nur verschoben.

Und schon mein Opa hat immer gesagt
[spoiler] was Du heute kannst besorgen…[/spoiler]

bye
TT

[QUOTE=Timothy_Truckle;28447]Nein.
split() benötigt den kompletten String im Speicher. Je nach dem wie groß die Datei sein kann wäre das nicht ratsam.

bye
TT[/QUOTE]

Naja ist natürlich richtig, aber wenn er die Daten verarbeiten will wird er wohl in irgendeiner Form den String parsen müssen… Man könnte die zu verarbeitenden Daten höchstens in kleinere Häppchen aufteilen…

[QUOTE=Aldimann]Naja ist natürlich richtig, aber wenn er die Daten verarbeiten will wird er wohl in irgendeiner Form den String parsen müssen… Man könnte die zu verarbeitenden Daten höchstens in kleinere Häppchen aufteilen…[/QUOTE]Und [JAPI]BufferedReader[/JAPI].readLine() liefert genau die gewünschten Häppchen. (oder man nimmt gleich einen JSON-Parser…)

bye
TT

Auch wieder richtig, wenn er allerdings den Kontext nicht verlieren will ist es mit einem readLine allein nicht getan (ich nehme mal an das er später noch wissen will welche Daten zu welchem Block gehören usw…)

@TO: Wie sollen denn die Daten weiterverarbeitet werden? Ich nehme mal an es bleibt nicht dabei jeden Zeile einzeln in ein Array einzulesen. Sondern du willst ja vermutlich den Value zu einem Key auswerten. Daher macht es Sinn, wie von TT beschrieben eine entsprechende Klasse dafür zu schreiben.

Das würde heißen irgendwie readline, schauen ob “contactstatus {” drin steht, falls ja new ContactStatus, falls nein schauen ob es “}” ist, ansonsten den Value und Key über spilt("=") trennen, dann den Value in dem zum Key passenden Attribut speichern. Sollte in readline “}” stehen dann halt das ContactStatus Objekt in einer Liste ablegen (gibt ja wohl mehrere von den Objekten)…

Andere Idee: Ggf. über java.util.Scanner, ansonsten ggf. der JSON-Parser da kenne ich mich aber nicht mit aus :)…

Ich kämpfe mich langsam nach vorne…jedoch scheitere ich daran, mit welchem Algorithmus ich die einzelnen Zeilen in eine List bringen kann.

Könnt ihr mir hier noch Unterstützung geben.

GGK

Das ist aber kein JSON. In JSON sähe das ungefähr so aus:

{"contactstatus": {
    "contact_name": "nagios-schwaz",
    "modified_attributes": 0,
    "modified_host_attributes": 0,
    "modified_service_attributes": 0,
    "host_notification_period": "24x7",
    "service_notification_period": "24x7",
    "last_host_notification": 1368003695,
    "last_service_notification": 1376907838,
    "host_notifications_enabled": 1,
    "service_notifications_enabled": 1
}
}

ich glaub…jetzt hab ich es kapiert…für jedes “Feld” erzeuge ich ein ContactStatus Objekt.

Mein erster Ansatz war, die Zeilen zwischen den geschwungenen Klammern auf einen Wisch zu parsen…

GGK

Ersetze “Feld” durch Block (alles zwischen zwei geschweiften Klammern) dann sind wir auf einer Wellenlänge ;)…

Ansonsten müsstest mir deine Idee nochmal erklären…

ich kann “Feld” nicht durch Block ersetzen.

Wie willst du denn einen gesammten Block (=das was zwischen den beiden geschwungenen Klammern steht) in ein Array bringen?

GGK

Eben NICHT in ein Array…

Alle Blocks werden durch eine Liste (wenns sein muss auch Array, tendenz wegen variabler Länge aber eher zu ersterem) von ContactStatus Dargestellt. Jeder Block entspricht einer Instanz (Objekt) der Klasse ContactStatus und jedes “Feld” einem Attribut der Klasse ContactStatus. U know?

Wenn Feld/Block beginnt ( zu erkennen an “{” ), erzeuge neues Array. Befülle Array solange bis Feld/Block endet ( zu erkennen an “}” ). Die einzelnen Arrays dann noch in eine List stecken, damit sie nicht “verloren” gehen.

Yes…I know…so bin ich ja dran…

Ich scheitere aber noch am Algorithmus…

ein kleiner Programm-Schnipsel…ich habe folgendes

      final BufferedReader bufferReader = new BufferedReader(new InputStreamReader(in));
      for (String s; (s = bufferReader.readLine()) != null;) {
	
			if (s.contains("servicestatus {")) {
				ContactStatus contactStatus = new ContactStatus();  				
				contactStatus.host_name();
			}

      }

Meine einfache Frage die mir derzeit nicht wirklich einfach erscheint:
wie schnappe ich mir die Zeilen der Blöcke…ich komme aus der ersten gefundenen Zeile einfach nicht raus

GGK

Also geht es erstmal darum eine Textdatei zeilenweise einzulesen?
http://www.javahowto.de/sprache/io/zeilenweise-lesen.html