Java - Problem beim Dateien schreiben

blauerninja

Cadet 4th Year
Registriert
Apr. 2011
Beiträge
65
Hallo Leute,
vorab: ich hab das Internet schon durchforstet, um zu verstehen wie in Java ein Output in eine Datei geschrieben wird. Allerdings wird bei mir die Datei nicht gefüllt, sprich bleibt leer. Vllt seht ihr etwas, was ich übersehe.

Vorhaben: ich habe einen Primzahlentest durchgeführt. Ein boolean-Array von 0 bis n. true sind die Primzahlen, diese sollen nun in einer for-Schleife ausgelesen, in einem String zwischengespreichert werden (da Java einen Stream in Bytes zerlegt und weiterverarbeitet, richtig?) und wenn der String einen entsprechende Länge hat, soll er in eine Datei gespeichert werden. Danach wird der String geleert und mit den weiteren Zahlen gefüllt. Solange bis alle Zahlen abgearbeitet wurden.

Hier das entsprechende Codestück:


boolean[] prim;
int count = 0;
String sb = "";
File datei = new File("primes.txt");
FileWriter output;
===============================
for (int i = 2; i < prim.length; i++) {
if (prim) {
sb += i + " ";
++count;
}
if (count == 5) {
sb += "\n";
count = 0;
}

if (sb.length() > 10000){
try {
output = new FileWriter(datei, true);
output.write(sb);
output.close();
sb = "";
} catch (IOException e) { }
}
} // Ende for ()


So wie ich das jetzt verstehe, wird ein neuer Filewriter erstellt und mit dem Inhalt der Datei primes.txt (exestiert bereits) gefüllt. Dann wird der String hinten drangehängt. Mit close() wird der Output ans Betriebssystem weitergegeben, das den Output in die Datei umleitet, richtig? Zum Schluss leere ich den String.
Wie gesagt, die Datei bleibt leer. Bei den Leuten, wo ich dieses Vorgehen abgeschrieben habe, funktioniert es. Was mach ich falsch?

Vielen Dank schon im Vorraus. Und ja, nicht ganz kompliziert schrieben. Ich kenn mich zwar mit Objektorientierung aus, aber einen ganz tiefen Einblick habe ich in Java noch nicht.^^
 
Der Count wird doch bei 5 wieder auf 0 gesetzt, kann dann ja nicht funktionieren.

Wenn ich das richtig verstehe dürften nur 5 Primzahlen in der Txt stehen bzw garkeine, da unten steht das er das erst bei 10000 eintragen soll.

Code:
[FONT=Courier New]if (sb.length() > 10000){
[/FONT]


Ist auch falsch müsste doch
Code:
[FONT=Courier New]if (sb.length() > 5){[/FONT]
sein.
Hier wird ja die Zeichenlänge abgefragt bei einer Zahl die 5 stellig ist, müsste es auf 5 geprüft werden.
 
Zuletzt bearbeitet:
prim.length ist 0

damit entspricht i < prim.length dem Vergleich 2 < 0,

der ist falsch, damit wird die Schleife nicht ausgeführt und

damit bleibt wie MacGyver angedeutet hat sb ein leerer String und

damit wird die Datei nicht geschrieben.
 
oh gott, MacGyver hat Recht. Ich hab nur 1000 eingegeben zum Testen. Klar klappts dann nicht :( Peinlich. Mit 200.000 klappts super.
Sorry! Danke aber für eure Hilfe. Kann man den Thread wieder löschen? Da er iwie nutzlos ist, wär dies wohl am Besten...
 
Der Thread sollte stehen bleiben, als mahnendes Beispiel was passiert wenn man Code einfach so guttenbergt :D

PS: Ich weiß ja nicht was das mit den 10000 für nen Sinn haben soll, aber ich schätze mal, dass es darum geht nicht jede Zahl einzeln wegzuschreiben und so die Last etwas zu verringern.

Das erreicht man auch ohne diese 10000'er Schleife mit BufferedWriter. Kannste dir ja mal anschauen. Dann kannst du dir auch sicher sein, dass alle auszugebenden Dinge auch ausgegeben werden.
Denn so musst du schon als Zielwert ein vielfaches von 10000 eingeben, damit die Funktion korrekt arbeitet. Wenn du statt 200000 einfach mal 205000 eingibst wirst du sehen dass wieder Werte fehlen.
 
Zuletzt bearbeitet:
genau. wollt dass der string ein einziges mal geschrieben wird, allerdings scheint es eine obere grenze in java für die stringlänge zu geben. bei 1 Mio hat das prog ewig gearbeitet ohne dass sich etwas getan hätte. die berechnung der primzahlen an sich geht in 5sec, daran lags nicht.
 
Was auch kein Wunder ist, wenn man die internen Abläufe von Java kennt.

Code:
sb += i + " ";
Dieses sollte man bei Zeitintensiven Algorithmen tunlichst vermeiden. Am Besten generell vermeiden, auch wenns schön einfach ist. Java erzeugt bei dieser Operation jedes Mal ein neues Objekt. Also es wird jedes Mal neuer Speicher reserviert. Eine Speicherreservierung ist recht zeitintensiv. Aus diesem Grund gibt es auch die Klasse StringBuilder, die um das 10.00-fache schneller Strings aneinanderreiht, da hier nur Speicher reserviert wird, wenn der Puffer zu klein wird.

Aber ich nehme mal an, dass du einfach den Quellcode irgendwo kopiert hast und dann den StringBuilder in ein String umgewandelt hast. Anders kann ich es mir nicht erklären, warum der String sb heißt. sb ist nämlich die Abkürzung für StringBuilder.
 
zuerst hab ich tatsächlich versucht mit einem StringBuilder zu arbeiten, was iwie nicht funktioniert hat. Habs übrigens aus einem Java-Buch, mit dem ich arbeite. Rauskopiert hab ich nur, wie man Dateien schreibt, da Javadoc und mein Buch in dieser Hinsicht nur einen Überblick über die Methoden geben.
Zu StringBuilder nochmal: hab im Web rausgefunden, dass der Puffer 5000 Zeichen beträgt, danach wird neuer Speicherplatz angefordert, was zeitintensiv sei. Ist es besser nach 5000 Zeichen in die Datei zu schreiben oder die Anforderung in Kauf zu nehmen? Wie würdet ihr in meinem Fall vorgehen?
 
Die maximale Kapazität eines StringBuilders (und eines Strings) ist Interger.MAX_VALUE (aber wahrscheinlich wird dir vorher der Speicher voll laufen).

Nimm wie MacGyver schon gesagt hat den BufferedWriter, dafür ist der da.
Writes text to a character-output stream, buffering characters so as to provide for the efficient writing of single characters, arrays, and strings.
The buffer size may be specified, or the default size may be accepted. The default is large enough for most purposes.
 
Zurück
Oben