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 | }
|
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
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++;
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!!!
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)
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...
1 | System.out.println(readData(4,1,new File("C://Users//501999277//Desktop//database//Sensoren.txt")));
|
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
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
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.
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
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.
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 :
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
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?
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!
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.
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.
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)
...
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. :-(
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.
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.
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.
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.
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.
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.
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.
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.
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?
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()
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...!
Du machst:
"DeviceID".equals(splitArray[0]
Was meinst du, ist "DeviceID" und "DeviceID " wirklich gleich?
Oh, na klar... Hab zuerst gedacht das macht nix aus, aber nach
ausführlichem hinschreiben ==> agree!
Vielen Dank!
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.
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.
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.
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... :-)
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....
Schau dir die Klasse SimpleDateFormat an.
Ansonsten musst du das halt von Hand erledigen.
geteilt und Modulo sind die Zauberfunktionen.
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.
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.
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.
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.
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.
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.
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.
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...
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ß
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.
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);
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.
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.
|