Forum: PC-Programmierung JAVA - In best. Zeile schreiben


von Markus H. (gammeltante)


Lesenswert?

Grüß euch zusammen,
ich habe eine Methode readData geschrieben, die eine bestimmte Zeile 
liest (Scanner) und danach mit split teilt. Angenommen ich habe folgende 
Daten:

DeviceID         :WD2012

Dann gibt mir die Funktion das WD2012 zurück.

Frage:
Jetzt möchte ich gerne diese DeviceID ändern und dafür eine Methode 
writeData schreiben. Gibt es etwas umgekehrtes zur Klasse Scanner und 
split, also anstatt Strings zu lesen diese zu schreiben. Oder muss ich 
da umständlich die Positionen ermitteln und dann mit der Klasse Writer 
arbeiten?
Am schönsten wäre es, wenn ich wie bei readData die Zeile, Spalte und 
den Pfad der Datei angeben könnte.

Zum besseren Verständnis mein Code readData
1
    public static String readData(int row, int column, String path) {
2
        String test = "0";      //ist nicht schön gelöst, vllt hat jemand eine Idee wie ich die Variable nicht vorbelegen muss...?
3
4
        try {
5
            Scanner scanner = new Scanner(new File(path));
6
7
            for (int i = 0; i < row; i++) {
8
9
                test = scanner.nextLine();
10
11
                String[] splitArray = test.split(":");
12
13
                test = splitArray[1];
14
            }
15
            scanner.close();
16
            
17
        } catch (IOException e) {
18
//            e.printStackTrace();
19
            System.out.println("Kein Wert in der Tabelle!!!");
20
        }
21
        return test;
22
    }

von Udo S. (urschmitt)


Lesenswert?

Strings sind in Java immutable. Das bedeutet, daß du keinen 
existierenden String verändern kannst. Es wird immer ein neuer String 
entstehen.
Wo ist das Problem den neuen String aus:

Markus H. schrieb:
> String[] splitArray = test.split(":");
>
>                 test = splitArray[1];

String neueZeile = splitArray[0] + ":" + neuerWert;

zu erzeugen.
Den neuen String kannst du jetzt der Variable zuweisen / als Returnwert 
zurückgeben etc. pp

von Udo S. (urschmitt)


Lesenswert?

Markus H. schrieb:
> String test = "0";      //ist nicht schön gelöst, vllt hat jemand eine Idee wie 
ich die Variable nicht vorbelegen muss...?

Was soll daran nicht schön sein?
Lokale Variablen sind halt auf dem Stack und werden nicht initialisiert. 
Also ist das das normalste der Welt.

ps. Les dir die Grundlagen zu Strings in deinem Java Buch genau durch. 
Das ist WICHTIG und ein Unterschied zu C C++;

von Markus H. (gammeltante)


Lesenswert?

Hallo Udo,

na logisch! Wieder was gelernt...

Jetzt bleibt mir aber noch eine Frage:

Wenn meine Daten jedoch mehrzeilig sind, also z.B.:

DeviceID          :WD2012
DeviceName        :Festplatte
DeviceHersteller  :Western Digital

Ist es möglich nur eine einzelne Zeile zu verändern (wie beim lesen mit 
dem Scanner) oder muss ich die kompletten Daten als String 
zusammenfassen und anschließend schreiben?

Vielen Dank!!!

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Markus H. schrieb:
> Oder muss ich da umständlich die Positionen ermitteln
> und dann mit der Klasse Writer arbeiten?
Arbeiten mit Textfiles ist Umständlich...

Deine Programmstruktur ist auch eher suboptimal, Scanner macht an der 
Stelle nicht so wirklich Sinn. So was muss/sollte man über reader und 
writer abhandeln.
1
public static String readData(int row, int column, File file) throws IOException,
2
      IllegalArgumentException {
3
    BufferedReader reader = new BufferedReader(new FileReader(file));
4
    try {
5
      String line = null;
6
      for (int i = 0; i < row; i++) {
7
        line = reader.readLine();
8
      }
9
      if (line == null) {
10
        throw new IllegalArgumentException("The file does not contain " + row + " rows!");
11
      }
12
      String[] splitArray = line.split(":");
13
      if (splitArray.length > 1) {
14
        return splitArray[1];
15
      } else {
16
        throw new IllegalArgumentException("The file does not contain valid data at row "
17
            + row + ", data read was: " + line);
18
      }
19
    } finally {
20
      reader.close();
21
    }
22
  }

Besser wäre es hier jedoch am Anfang alle Daten in eine passende 
Datenstruktur einzulesen, zu verändern und dann ggf. wieder in eine 
Datei rauszuschreiben.

So wird das ganze nur unötig kompliziert (woher weiss der Aufrufer die 
zeilennummer? Was ist bei leer/kommentarzeilen etc. pp)

von Markus H. (gammeltante)


Lesenswert?

Hallo Läubi,
danke für deine Antwort!

Ich wollte gerade deinen Code testen aber ich übergebe in der main 
folgendes:
1
        System.out.println(readData(4,1,"C://Users//501999277//Desktop//database//Sensoren.txt"));

Logische Fehlermeldung:  argument java.lang.String cannot be converted 
to java.io.File

file ist doch ein Objekt der Klasse File. Wie kann ich diesem Objekt 
jetzt seinen Ursprungsort zuweisen?

Meinst du mit passender Datenstruktur ein Array-Feld[][]? Mehrere Zeilen 
und zwei Spalten...

von Hans M. (hansilein)


Lesenswert?

1
 System.out.println(readData(4,1,new File("C://Users//501999277//Desktop//database//Sensoren.txt")));

von Markus H. (gammeltante)


Lesenswert?

Jetzt hat sich noch ein vermutlich letzter Fehler eingeschlichen:

Bezieht sich auf die erste Zeile in Läubis Code

unreported exception java.io.IOException; must be caught or declared to 
be thrown

von Udo S. (urschmitt)


Lesenswert?

Markus H. schrieb:
> file ist doch ein Objekt der Klasse File.

Markus Markus, ich hatte dir doch schon vor einigen Tagen ein paar 
Kapitel ans Herz gelegt.
Les mal das über IO über Streams und Reader/Writer, und schau dir mal 
die Klasse File in der Java Doku an.

Viel Spass

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Markus H. schrieb:
> unreported exception java.io.IOException; must be caught or declared to
> be thrown

a) Entweder die Exception in der methode wieder "erfen" per throws oder 
ein try/catch drum herum.

Markus H. schrieb:
> einst du mit passender Datenstruktur ein Array-Feld[][]
Auch wenn ein Array eine Datenstruktur ist glaube ich kaum das dies hier 
passend ist.

Da du nicht schreibst was du eigentlich erreichen möchtest ist es halt 
schwer Tips zu geben.

Allgemein solltest du dich aber sowieso erst mal mit Programmieren und 
java auseinandersetzen sonst wird das nix.

von Markus H. (gammeltante)


Lesenswert?

Hallo Udo,
entschuldige wenn ich mich so blöd anstelle.
Ich bin mit null Programmiererfahrung in meiner gelernten 
Programmiersprache (C/C++) jetzt auf Java umgestiegen und soll innerhalb 
von einem Monat ein recht umfangreiches Programm erstellen. Aufgrund des 
Zeitmangels versuche ich möglichst parallel zu arbeiten was öfters 
Verwirrung mit sich bringt.
Keine Sorge, ich habe fleißig gelesen! Nur leider auch viel vergessen 
(zu viel Input auf einmal...)

Im Inselbuch habe ich jetzt glaub ich schon 3 Mal das Kapitel über 
Reader/Writer gelesen. Die geben das Gelesene aber jedes Mal nur aus und 
packen es nicht in eine geeignete Datenstruktur hinein. Das wäre ja 
(auch laut Läubi) sinnvoll.
Ich suche schon länger nach einem einfachen Beispiel für eine Anwendung 
wo etwas gelesen wird, anschließend ein Teil verändert und dann wieder 
geschrieben. Ich will das auch nicht einfach nur abschreiben, sondern 
verstehen und dann selbst für meine Anwendung schreiben. Aber so ein 
Beispiel habe ich noch nirgendwo gefunden.

Vielen Dank auf jeden Fall schon mal für eure Hilfe!
Markus

von Läubi .. (laeubi) Benutzerseite


Angehängte Dateien:

Lesenswert?

Markus H. schrieb:
> Ich bin mit null Programmiererfahrung in meiner gelernten
> Programmiersprache (C/C++) jetzt auf Java umgestiegen und soll innerhalb
> von einem Monat ein recht umfangreiches Programm erstellen.

Dann wäre jetzt der Perfekte Zeitpunkt zum "Auftraggeber" zu gehen und 
zu sagen das du das in der Zeit nicht leisten kannst.

Markus H. schrieb:
> Die geben das Gelesene aber jedes Mal nur aus und
> packen es nicht in eine geeignete Datenstruktur hinein

Und wo ist das Problem? Statt ausgeben muss man es dann halt in die 
Datenstruktur schreiben.

Markus H. schrieb:
> Ich suche schon länger nach einem einfachen Beispiel für eine Anwendung
> wo etwas gelesen wird, anschließend ein Teil verändert und dann wieder
> geschrieben.

Siehe Anhang, Aufruf dann z.B. so:
1
public static void main(String[] args) throws IOException {
2
  File file = new File(args[0]);
3
  Device device = Device.read(file);
4
  device.setName("Neuer Toller Name");
5
  Device.write(file, device);
6
}

Markus H. schrieb:
> Aufgrund des Zeitmangels versuche ich
> möglichst parallel zu arbeiten
Ganz schlechte Idee das wird schief gehen.

von Markus H. (gammeltante)


Lesenswert?

Hallo Läubi,
danke für deinen Hinweis, ich hab schon mit den try-catches 
herumprobiert aber es hat nicht funktioniert. ==> Ich probiers aber 
gleich nochmal!


Nochmal von vorne Beschrieben:

Es soll eine Anwendung entstehen, die hilft einen Systemausfall 
vorherzusagen.
Dazu soll ein Dienst im Hintergrund laufen, der alle X Minuten die 
Temperatursensoren auf der Festplatte, den SMART-Status der Festplatte, 
die Drehzahl des Lüfters, einen Sensor für Vibration,... ausließt. Diese 
ausgelesenen Daten sollen dann natürlich in ein Log File geschrieben 
werden.
Bevor jedoch die aktuelle Temperatur eingetragen wird soll der alte mit 
dem neuen Wert verglichen werden. Ist der alte Wert höher wie 60°C und 
der neue auch soll ein weiterer Wert(Temp innerhalb X > 60°C) um X 
hochgezählt werden. Ebenso soll dies noch mit anderen Werten 
(Betriebsstunden, etc...) gemacht werden.
Das bisherige erledigt regelmäßig der Dienst.
Jetzt muss es noch eine GUI geben, über die der Benutzer gewarnt wird, 
wenn was nicht mehr passt und um die Daten auf Wunsch anschauen zu 
können.

Bisher habe ich eine GUI Oberfläche (aber noch keine Verknüpfungen)
Aktuelles Arbeitsfeld: Daten von Sensoren einlesen (vereinfacht 
dargestellt als Sensoren.txt), dann die Daten verändern und anschließend 
in besagtes Log-File zu schreiben.

Bisher habe ich für jede Komponente ein eigenes Log-File angelegt. Diese 
sehe so oder ähnlich aus:

Festplatte.txt
1  DeviceID                           :WD2012xyz
2  DeviceName                         :Festplatte
3  DeviceHersteller                   :Western Digital
4  DeviceLetzterTausch                :02.01.2012
5  DeviceBetriebsstunden              :24
6  DeviceMaxBetriebsstundenNachMTBF   :5000
7  DeviceEinschaltzyklen              :3
8  DeviceMaximaleTemperatur           :
9  DeviceMinimaleTemperatur           :
10 DeviceTempDauerHigher              :
11 DeviceTempDauerLower               :
12 DeviceTempChangeFast               :
13 DeviceShockFlag                    :
14 DeviceVibrationFlag                :
15 DeviceSMARTStatus                  :

von Udo S. (urschmitt)


Lesenswert?

Zeig mal ein Beispiel und was du ändern möchtest.
Wenn es nur eine Textdatei ist nach dem Motto:

Schlüssel1: Wert1
Schlüssel2: Wert2
...

würde ich es zeilenweise lesen (geht am besten mit dem BufferedReader 
(siehe Beispiel von Läubi)) prüfen ob in der Zeile was geändert werden 
muss und die (evt. geänderte) Zeilen in eine neue Datei schreiben.
Wenn das alles geklappt hat kannst du die Originaldatei umbenennen, dann 
die neue in die OriginalDatei umbenennen und wenn das geklappt hat die 
umbenannte Originaldatei wegwerfen.
Wie man Files umbenennt findest du selbst raus. Sieh dir FILE an.
Wichtig: Manchmal muss man die Return Codes von Methoden auswerten.

Noch was: Wenn immer du irgendwas mit Ressourcen machst die geöffnet und 
geschlossen werden (File, db-Connection, etc) dann gewöhne dir von 
Anfang an das in ein try { } finally {} zu packen:

Reader x = NULL;
try {
  x = new ...

  //dein Code


} finally {
  if (x != null)
    x.close;
}

So stellst du immer sicher daß deine Ressourcen freigegeben werden

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Markus H. schrieb:
> danke für deinen Hinweis, ich hab schon mit den try-catches
> herumprobiert aber es hat nicht funktioniert.

Nicht probieren, versuchen zu verstehen, womit entwickelst du 
eigentlich? Z.B. unter eclipse gibt es gerade für solche "Standard" 
Dinge wie try/catch codevervollständigung, und in deinem ursprünglichem 
Beispiel war doch auch schon eins drin?

von Markus H. (gammeltante)


Lesenswert?

Mit NetBeans

von Markus H. (gammeltante)


Lesenswert?

Hans Mayer schrieb:
1
 System.out.println(readData(4,1,new
2
 File("C://Users//501999277//Desktop//database//Sensoren.txt")));

Ich hab nen Fehler gemacht. Die IOException bezog sich auf den Aufruf. 
Dort musste diese dann natürlich "gethrowt" werden... ==> jetzt gehts!

von Udo S. (urschmitt)


Lesenswert?

Markus H. schrieb:
> Bevor jedoch die aktuelle Temperatur eingetragen wird soll der alte mit
> dem neuen Wert verglichen werden. Ist der alte Wert höher wie 60°C und
> der neue auch soll ein weiterer Wert(Temp innerhalb X > 60°C) um X
> hochgezählt werden. Ebenso soll dies noch mit anderen Werten
> (Betriebsstunden, etc...) gemacht werden.

Versteh ich nicht ganz.
Du schreibst eine Tracedatei? Wie groß wird die?
Die hochgezählten Einträge werden wieder zurückgespeichert?

Diese Zähler würde ich im Programmspeicher in einem (oder von mir aus 
mehreren Objekt(en) lassen und zur Not beim Starten / Stoppen mit je 
einer Methode in eine Datei speichern/wieder laden.
Dir Trace Datei wird nur fortgeschrieben.

von Markus H. (gammeltante)


Lesenswert?

Ich möchte wissen, wie lange das Gerät einer Temperatur > 60°C 
ausgesetzt ist.
Dazu soll er mir einfach wenn der letzte und der neue Wert über 60° sind 
eine Variable hochzählen.
Diese steht im Log-File.

Wenn ich nur zu Beginn den Wert auslese und beim Beenden schreibe, 
könnte es passieren, dass mein System abstürzt und ich gar nix 
geschrieben habe. Angenommen das System fällt aus, weil die Temperatur 
zu groß wird, kann ich das später evtl. auf meinem Log-File 
nachvollziehen.

von Udo S. (urschmitt)


Lesenswert?

Markus H. schrieb:
> Angenommen das System fällt aus, weil die Temperatur
> zu groß wird, kann ich das später evtl. auf meinem Log-File
> nachvollziehen.

Das bedeutet du willst kein Log file (ein Log File ist fortlaufend und 
wird immer größer) sondern eine StatusFile das regelmäßig aktualisiert 
wird.

Dann hat dieses File noch nur eine bestimmte Anzahl von Werten.

Dann mach eine Klasse in der diese Werte als Variablen (Attribute) drin 
stehen.
In die Klasse ein read-Methode der eine bestehende Datei einliest und 
die Attribute deiner Klasse füllt.
Eine Write Methode die die aus den daten in der Klasse die Datei 
schreibt
Getter und Setter Methoden für alle Attribute, mit denen du die Werte 
ändern kannst
Jetzt kannst du die vorherige Datei lesen, die Werte über dein 
eigentliches Programm aktualisieren und wieder als Datei 
zurückschreiben.
Dazu so eine Mimik wie vorgeschlagen zum sicheren Rückschreiben 
(umbenennen)
...

von Mark B. (markbrandis)


Lesenswert?

Markus H. schrieb:
> Ich wollte gerade deinen Code testen aber ich übergebe in der main
> folgendes:
>
1
>         System.out.println(readData(4,1,"C://Users//501999277//Desktop//database//Sensoren.txt"));
2
>

Java als plattformübergreifende Sprache, dann aber hart die 
Windows-Dateipfade hineinkodieren - das macht einen beim Code Review 
ganz traurig. :-(

von Udo S. (urschmitt)


Lesenswert?

Mark Brandis schrieb:
> Java als plattformübergreifende Sprache, dann aber hart die
> Windows-Dateipfade hineinkodieren - das macht einen beim Code Review
> ganz traurig. :-(

na ja, Markus hat im Moment wohl noch ganz andere Probleme.

von Karl H. (kbuchegg)


Lesenswert?

Udo Schmitt schrieb:

> Dann mach eine Klasse in der diese Werte als Variablen (Attribute) drin
> stehen.
> In die Klasse ein read-Methode der eine bestehende Datei einliest und
> die Attribute deiner Klasse füllt.
> Eine Write Methode die die aus den daten in der Klasse die Datei
> schreibt
> Getter und Setter Methoden für alle Attribute, mit denen du die Werte
> ändern kannst
> Jetzt kannst du die vorherige Datei lesen, die Werte über dein
> eigentliches Programm aktualisieren und wieder als Datei
> zurückschreiben.
> Dazu so eine Mimik wie vorgeschlagen zum sicheren Rückschreiben
> (umbenennen)

Hätt ich auch vorgeschlagen.
Das ist doch Quatsch, da mit Zeilen und Spaltennummer rumzuhampeln.
Da kommt ein Wert dazu, und der Tanz geht los.

Das File wird gelesen und anhand des Zeilenanfangs erkennt das Programm 
um welchen Wert es sich handelt. Damit ist man schon mal ein gutes Stück 
von der exakten Filestruktur unabhängig geworden. Noch universeller 
wirds dann noch, wenn man ein XML File dafür einsetzt.

von Udo S. (urschmitt)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Das File wird gelesen und anhand des Zeilenanfangs erkennt das Programm
> um welchen Wert es sich handelt. Damit ist man schon mal ein gutes Stück
> von der exakten Filestruktur unabhängig geworden. Noch universeller
> wirds dann noch, wenn man ein XML File dafür einsetzt.

Brauchts nicht mal. Er hat doch so wie es aussieht immer
"Name  : Wert"
Also kann er doch nach "Namen" suchen. Ist wie ein einfaches Property 
file.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> Ist wie ein einfaches Property
> file.

Welches er mit der passenden Klasse sogar so einlesen könnte... Was aber 
alles mehr oder weniger hilfreich ist wenn einfache Programmkonstrukte 
nicht verstanden worden sind.

von Karl H. (kbuchegg)


Lesenswert?

Udo Schmitt schrieb:
> Karl Heinz Buchegger schrieb:
>> Das File wird gelesen und anhand des Zeilenanfangs erkennt das Programm
>> um welchen Wert es sich handelt. Damit ist man schon mal ein gutes Stück
>> von der exakten Filestruktur unabhängig geworden. Noch universeller
>> wirds dann noch, wenn man ein XML File dafür einsetzt.
>
> Brauchts nicht mal.

:-)
Der fertige XML Reader würde ihm das einlesen und rausschreiben abnehmen
:-)


Ich bin auch kein riesiger Fan von XML Files, aber ich muss auch 
zugestehen, dass sie so ihre Vorteile haben.

von Karl H. (kbuchegg)


Lesenswert?

Läubi .. schrieb:
> Udo Schmitt schrieb:
>> Ist wie ein einfaches Property
>> file.
>
> Welches er mit der passenden Klasse sogar so einlesen könnte... Was aber
> alles mehr oder weniger hilfreich ist wenn einfache Programmkonstrukte
> nicht verstanden worden sind.

Jau.
Dabei könnte man da so schön ein allgemein verwendbares 
Property-File-Konzept drum herum legen. Er hat ja mehrere Property Files 
mit unterschiedlichem Aufbau.
Aber ok, erst mal muss er sich auf die Basisdinge in Java konzentrieren, 
ehe man dann mit der Kür die Bonuspunkte einheimst.

von Udo S. (urschmitt)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ich bin auch kein riesiger Fan von XML Files, aber ich muss auch
> zugestehen, dass sie so ihre Vorteile haben.

Vor allem dort, wo man komplexere Datenstrukturen und vor allem 1:n 
Beziehungen abzubilden hat.
So wie ich Markus verstanden habe soll das File lesbar sein (Ähnlich 
einer Protokolldatei). Inwiefern er da Vorgaben hat weiss ich nicht.
Und bei seinem Kenntnisstand wollte ich ihm nicht die Funktion eines XML 
Parsers erklären wollen.

von Markus H. (gammeltante)


Lesenswert?

So,... ein neuer Tag mit neuen Programmieraufgaben ;-)

Also an dieser Stelle erst mal euch allen ein dickes Dankeschön, dass 
ihr euch so bemüht mir weiterzuhelfen!


Ich versuche jetzt anhand von Läubis Beispiel des "Readers" einen 
"Writer" zu entwickeln.

von Markus H. (gammeltante)


Lesenswert?

Grüß euch zusammen,
jetzt habe ich aber nochmal eine Frage:

Im Code von Läubi (Datum: 16.02.2012 13:08) findet sich eine set 
Methode:
1
    public void setId(String id) {
2
        this.id = id;
3
    }

Wenn ich folgendes Ursprungsfile habe passt alles:

DeviceID:XYZ

Aber bei jener Anordung setzt er einfach die id nicht:

DeviceID    :XYZ

Aufruf:
1
        try{
2
            String line = null;
3
            while((line = reader.readLine())!=null){                   String[] splitArray = line.split(":");      
4
                System.out.println(splitArray[0] + splitArray[1]);
5
                if(splitArray.length > 1){                  
6
                    
7
                    // # Device #
8
                    if("DeviceID".equals(splitArray[0]){
9
                               device.setId(splitArray[1]);

Das verstehe ich nicht!!!
Warum setzt der da die ID nicht?

von Udo S. (urschmitt)


Lesenswert?

Was zeigt der Debugger für den Wert von spliArray[0] an?
schau mal GENAU! hin.
Tipp: Die Klasse String hat eine Methode namens trim()

von Markus H. (gammeltante)


Lesenswert?

Das File sieht so aus: DeviceID   :XYZ

Der Debugger zeigt mir für splitArray[0] "DeviceID   " an.

Mit der trim() Methode kann ich die white spaces entfernen.

Aber eigentlich dürfen die ja gar nix machen oder?

Ich teile ja davor mit line.split(":") die Zeile auf und will 
anschließend das splitArray[1] ("XYZ") in meine Variable schreiben. Der 
String in splitArray[1] hat keine Whitespaces...!

von Udo S. (urschmitt)


Lesenswert?

Du machst:

"DeviceID".equals(splitArray[0]


Was meinst du, ist "DeviceID" und "DeviceID   " wirklich gleich?

von Markus H. (gammeltante)


Lesenswert?

Oh, na klar... Hab zuerst gedacht das macht nix aus, aber nach 
ausführlichem hinschreiben ==> agree!

Vielen Dank!

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Sorry das mit den Whitespace hatte ich übersehen, es sollte auch mehr ls 
Anregung den als Fertige Lösung zu verstehen sein, es gibt da noch 
einiges was man abprüfen könnte/sollte das würde hier aber zu weit 
führen.

von Udo S. (urschmitt)


Lesenswert?

Läubi .. schrieb:
> es gibt da noch einiges was man abprüfen könnte/sollte
Es geht hier ja auch wohl nicht um fertige Lösungen.
Deshalb habe ich Markus auch selbst mal suchen lassen.

Markus, so etwas musst du in Zukunft aber selbst finden, das sind 
absolute Basics in Stringverarbeitung, egal in welcher Sprache.

von Karl H. (kbuchegg)


Lesenswert?

Markus. Ein Tip

Wenn du Strings zur Kontrolle ausgibst (ich weiß, der Code kommt von 
Läubi), so wie hier

 System.out.println(splitArray[0] + splitArray[1]);

dann mach dir IMMER vor und hinter den String ein Sonderzeichen in die 
Ausgabe

  System.out.println( "#" + splitArray[0] + "#" + splitArray[1] + "#");


denn dann fällt es dir auf, wenn in der Ausgabe

  #DeviceID                           #WD2012xyz#
anstelle von
  #DeviceID#WD2012xyz#

oder

#DeviceID            #
anstelle von
#DeviceID#

steht. Detto, wenn im String noch Sonderzeichen wie ein Zeilenvorschub 
enthalten ist. Durch die Sonderzeichen, die den String einrahmen, sieht 
man den Unterschied zwischen

#DeviceID
#
und
#DeviceID#

Diese Sonderzeichen sind eine Möglichkeit, wie du Whitespace Zeichen 
zumindest soweit sichtbar machen kannst, dass du zumindest eine Chance 
hast, sie zu bemerken ohne dass du stundenlang an der falschen Stelle 
suchst.

von Udo S. (urschmitt)


Lesenswert?

Karl Heinz Buchegger schrieb:
> dann mach dir IMMER vor und hinter den String ein Sonderzeichen in die
> Ausgabe

Jepp, ich klammere bei jeder! Traceausgabe, Strings mit "'".

Was ham mer da schon Fehler gesucht... :-)

von Markus H. (gammeltante)


Lesenswert?

Danke für den Tip!

Das hab ich gemacht...

Ich code auch in Schleifen und so immer Sonderzeichen rein. Wenn ich das 
Programm dann laufen lasse und irgendwo Fehler auftreten finde ich die 
leichter, da ich sehen kann in welche Schleifen er rein geht und welche 
nicht...


Ich hab jetzt ein neues Problem bekommen:

Ich möchte mir die Zeitdifferenz zwischen der aktuellen Zeit und der 
letzten Zeit berechnen.
1
    public static long zeitDiff(Model model){
2
        Date aktuell = new Date();   
3
        Date old = model.getGeraetDateTime();
4
        long time = aktuell.getTime()-old.getTime();
5
        System.out.print(time);
6
        return time;
7
    }

Die Methode getGeraetDateTime(); soll mir einen private String 
geraetDateTime; "1300000000000" (Millisekunden seit 1970) in ein Date 
Objekt umwandeln.

Zuerst versuchte ich folgendes:
1
    public Date getGeraetDateTime(){
2
        Date datum = new Date(this.geraetDateTime);
3
        return datum;
4
    }

ABER der Konstruktor Date(String s) ist deprecated und außerdem erwartet 
er als simpleDateFormat formatierte Daten. Deshalb habe ich das hier 
versucht:
1
    public Date getGeraetDateTime(){
2
        System.out.println("### 1 ###");
3
        long millis = Long.parseLong(geraetDateTime);
4
        System.out.println("### 2 ###");
5
        Date datum = new Date(millis);
6
        System.out.println("### 3 ###");
7
        return datum;
8
    }

Aber auch hier spuckt er mir in der 3.Zeile eine NumberFormatException: 
null aus...???

Soweit ich die API verstanden habe müsste er erst den String in einen 
Long parsen und anschließend den Long dann in ein Date Objekt 
umwandeln....

von Udo S. (urschmitt)


Lesenswert?

Schau dir die Klasse SimpleDateFormat an.

Ansonsten musst du das halt von Hand erledigen.
geteilt und Modulo sind die Zauberfunktionen.

von Karl H. (kbuchegg)


Lesenswert?

Markus.

Du musst etwas systematischer vorgehen.
1
    public Date getGeraetDateTime(){
2
        System.out.println("### 1 ###");
3
        long millis = Long.parseLong(geraetDateTime);
4
        System.out.println("### 2 ###");
5
        Date datum = new Date(millis);
6
        System.out.println("### 3 ###");
7
        return datum;
8
    }
> Aber auch hier spuckt er mir in der 3.Zeile eine
> NumberFormatException: null aus...???

Schau dir deinen Code an. Du machst da zwar Ausgaben, aber was bringen 
die dir? Nichts! Wo es ein Problem gibt, würdest du auch in deinem 
Debugger sehen, wenn du den Code in Einzelschritten durchgehst.

Wonach klingt die Fehlermeldung?
Langsam lesen -   Number ... Format .... Exception

Number ...... da ist also von Zahlen die Rede
Format ...... irgendetwas mit einer Formatierung
Exception ... irgendetwas stimmt damit nicht

Eine Formatierung hat meistens etwas mit Text zu tun. Ein Number Format 
wird also etwas mit der textuellen Darstellung von Zahlen zu tun haben.
Wo in deinem Code kann so etwas auftreten?
Na zb dort, wo du den Text aus geraetDateTime in einen long parsen 
lässt.

Was wird daher, wenn du schon Ausgaben machst, vernünftig sein 
auszugeben?
Na, da lass ich mir doch mal geraetDateTime ausgeben (mit einem 
Sonderzeichen davor und dahinter) und sehe erst mal nach, ob dieser Text 
überhaupt eine Zahl sein kann! Wenn da "schnurdibur" drinnen steht (aus 
welchem Grund auch immer), dann weiß ich, dass ich ergründen muss, wie 
der Text da hinein gekommen ist. Wenn da so etwas wie "1234" drinnen 
steht, dann muss ich weiter schaun. Dann lass ich mir eben als nächstes 
mal den entstandenen long ausgeben und sieh mal nach, ob der vernünftig 
aussieht.
etc. etc.

Deine jetzigen Zwischenausgaben kannst du in der Pfeife rauchen. Die 
bringen dir nichts. Wenn du Ausgaben machst, und da spricht erst mal 
nichts dagegen, dann musst du die so machen, dass du von der Ausgabe 
auch einen Nutzen hast! Ja! Man kann Variablen ausgeben um so zu sehen, 
welchen Wert sie haben und zu verfolgen, wie sie sich im Programmlauf 
verändern.

Ansonsten kannst du die Ausgaben nämlich auch gleich bleiben lassen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wenn da "schnurdibur" drinnen steht

Ich würde mal behaupten das der Wert nicht initialisiert also null 
ist...

Abgesehen davon bringt es aber nichts immer von einem Fehlerchen zum 
nächsten zu stolpern und hoffen das einem das schon jemand löst.

von Udo S. (urschmitt)


Lesenswert?

Läubi .. schrieb:
> Abgesehen davon bringt es aber nichts immer von einem Fehlerchen zum
> nächsten zu stolpern und hoffen das einem das schon jemand löst.

Jepp, deshalb gibts nur noch Hinweise, zumal sein Ansatz nicht zu seinem 
eigentlichen Problem passt.

Markus H. schrieb:
> Ich möchte mir die Zeitdifferenz zwischen der aktuellen Zeit und der
> letzten Zeit berechnen.

Markus H. schrieb:
> Die Methode getGeraetDateTime(); soll mir einen private String
> geraetDateTime; "1300000000000" (Millisekunden seit 1970) in ein Date
> Objekt umwandeln.

von Karl H. (kbuchegg)


Lesenswert?

Läubi .. schrieb:

> Abgesehen davon bringt es aber nichts immer von einem Fehlerchen zum
> nächsten zu stolpern und hoffen das einem das schon jemand löst.

Jepp.
Ist halt das leidige Syndrom 'Da schau ich mal in der Lösung nach', hier 
in der Form eines 'Forensyndrom'.

Sobald man mitkriegt, dass es eine einfache Möglichkeit gibt, sich die 
Lösung ohne eigenes Kopfzerbrechen zu beschaffen, wird das gerne in 
Anspruch genommen. Hier im Forum dann eben: Noch eine Fehlermeldung - da 
überleg ich gar nicht lange, sondern poste die Meldung ins Forum.

Und das ist jetzt gar nicht mal so sehr auf den TO gemünzt. Ist ein 
generelles Problem: Wie weit hilft man jemandem, in dem man ihm Lösungen 
fertig präsentiert? Und wie macht man ihm klar, dass Hilfe nicht 
bedeutet, dass ab sofort das Forum für jeden Pfurz verantworlich ist.

von Udo S. (urschmitt)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und das ist jetzt gar nicht mal so sehr auf den TO gemünzt. Ist ein
> generelles Problem: Wie weit hilft man jemandem, in dem man ihm Lösungen
> fertig präsentiert?

Aus dem Grund kriegt er von mir im Moment nur Hinweise welche Klassen er 
sich mal anschauen soll. Ich kann es verstehen wenn du vor der riesigen 
Klassenbibliothek erst mal wie der Ochs vorm Berg stehst.
Aber irgendwie tut sich Markus schon ziemlich schwer seine Probleme 
runterzubrechen, zu zerlegen und sich selbst Lösungsstrategien 
auszudenken.
Das sieht manchmal wie planloses rumprobieren aus.
Na ja ich drücke ihm die Daumen daß sich bei ihm noch der richtige 
Schalter umlegt.

von Karl H. (kbuchegg)


Lesenswert?

Udo Schmitt schrieb:
> Aus dem Grund kriegt er von mir im Moment nur Hinweise welche Klassen er
> sich mal anschauen soll. Ich kann es verstehen wenn du vor der riesigen
> Klassenbibliothek erst mal wie der Ochs vorm Berg stehst.

Oh. Überhaupt keine Frage.
Geht mir genau so.

> Aber irgendwie tut sich Markus schon ziemlich schwer seine Probleme
> runterzubrechen, zu zerlegen und sich selbst Lösungsstrategien
> auszudenken.
> Das sieht manchmal wie planloses rumprobieren aus.

Da orte ich das eigentliche Problem. Die Fähigkeit sich selbst zu helfen 
und nicht an der nächsten Fehlermeldung zu zerbrechen, weil man im 
ersten Moment so überhaupt keinen Tau hat, was das jetzt wieder sein 
könnte.

Natürlich ist einem das nicht in die Wiege gelegt und das muss man 
lernen und sich erarbeiten. Wer allerdings industriell programmiert (und 
ich meine mich zu erinnern, dass das irgendwann im Thread mal vorkam), 
der sollte m.M nach die entsprechenden Techniken dazu schon 
einigermassen entwickelt haben. Und das ist das, was mich immer ein 
bischen traurig macht, wenn ich sehe wie sich der 'Nachwuchs' in ein 
Abenteuer stürzt, dem er nicht gewachsen ist.

von Markus H. (gammeltante)


Lesenswert?

Danke für eure Antworten!

Ich habe schon verstanden, dass da ein Fehler mit dem parsen der 
Ursprungsdaten vorliegt (Zahlen, Formatierung,...).

Nachdem ich mir schon recht lange über genau diesen Teil den Kopf 
zerbreche und in meiner Java-Unsicherheit alles mögliche ausprobiert 
habe hab ich den Code hier gepostet um zu erfragen ob ich einen Fehler 
im Code habe. Davor habe ich in der 
API(SimpleDateFormat,String,DateFormat,Long,...) nach anderen 
Möglichkeiten zum Parsen gesucht. Ich habe auch anstelle des Strings ein 
Date Attribut ausprobiert...

Ich habe den Fehler inzwischen gefunden. Ich habe schlichtweg übersehen 
dem Attribut beim Einlesen den String Wert zuzuweisen ==> Deshalb auch 
null... (wie Läubi vermutet hat)

Auf jeden Fall berechnet mir das Programm jetzt die Zeitdifferenz.


@Udo Schmitt: Warum passt mein Ansatz nicht zu meinem Problem? Das 
verstehe ich nicht.

von Markus H. (gammeltante)


Lesenswert?

Hallo Karl Heinz Buchegger,

industrielle kann man das nicht unbedingt nennen...
Ich schreibe die Anwendung für meine Hochschule als Projekt.
Und... es ist mein erstes Programm mit GUI und größerer Logik usw...
Es ist mein erstes Java Programm

Ich selber bin der Meinung, dass das Projekt vom Umfang viel zu 
umfangreich ist, aber ... - da muss man durch...

von Udo S. (urschmitt)


Lesenswert?

Markus H. schrieb:
> @Udo Schmitt: Warum passt mein Ansatz nicht zu meinem Problem? Das
> verstehe ich nicht.
Weil ein Date Objekt das du mit der Differenzzeit als long instanziierst 
nur das Datum seit dem 1.1.1970 anzeigt. Gut man kann da natürlich 
Sekunden, Minuten, Stunden herausziehen.
Aber vieleicht habe ich dich auch falsch verstanden oder du weisst 
diesmal mehr als ich :-). In dem Fall nehm ich geren Belehrungen an.

Immer weiter in dem Java Buch lesen. Das ist ein wesentlicher Schlüssel 
zum Erfolg.
Gruß

von Markus H. (gammeltante)


Lesenswert?

Mit public long getTime() bekomme ich die Anzahl der Millisekunden seit 
1.1.1970.
Ich merke mir die Millisekunden vom letzten Aufruf.
Somit kann ich dann aus dem neuen Wert und dem alten Wert die 
Millisekunden-Differenz berechnen.

Angenommen die Temperatur des Rechners ist bei der ersten Messung größer 
70°C und bei der zweiten auch. Die Logik erkennt das und addiert dann 
die Differenz zu der bisherigen Zeit in der der Rechner heißer als 70°C 
war.

von Udo S. (urschmitt)


Lesenswert?

Markus H. schrieb:
> Mit public long getTime() bekomme ich die Anzahl der Millisekunden seit
> 1.1.1970.
> Ich merke mir die Millisekunden vom letzten Aufruf.
> Somit kann ich dann aus dem neuen Wert und dem alten Wert die
> Millisekunden-Differenz berechnen.

Das ist schon klar, aber warum initialisierst du mit dieser Anzahl 
Millisekunden wieder ein Date Objekt? Dort wird es nur als Datum/Uhrzeit 
ab 1.1.1970 0:0 interpretiert. Das meinte ich.

Markus H. schrieb:
> Date datum = new Date(millis);

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> as ist schon klar, aber warum initialisierst du mit dieser Anzahl
> Millisekunden wieder ein Date Objekt?

Eventuell möchte er das weiterverarbeiten oder im Logfile ausgeben oder 
oder ... die paar ms werden sein Programm nicht signifikant verlangsamen 
und konkrete Datenstrukturen sind immer gut.

Ansonsten gibt es auch System.currentTimeMillis() falls man wirklich nur 
am aktuellem Zeitstempel interessiert ist, dafür muss man kein neues 
Date Objekt erzeugen.

von Udo S. (urschmitt)


Lesenswert?

Läubi .. schrieb:
> Eventuell möchte er das weiterverarbeiten oder im Logfile ausgeben oder
> oder ... die paar ms werden sein Programm nicht signifikant verlangsamen
> und konkrete Datenstrukturen sind immer gut.

Nein darin steht eine Zeitdauer, also die Differenz zweier .getTime() 
Aufrufe.
Das war ja das Ursprungsproblem.
Wie ich oben schon gesagt hatte könnte man natürlich ein Date Objekt 
jetzt dazu missbrauchen sich die Zeit formattiert in Stunden Minuten und 
Sekunden über die deprecated Funktionen getSeconds() getMinutes() ... 
ausgeben zu lassen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.