Generierung von CSV-Dateien mit Java

8

In unserem Projekt müssen wir alle zwei Stunden eine große CSV-Datei mit einem Java-Programm erstellen.

Diese Datei enthält ca. 60.000 Zeilen (ca. 120 Zeichen pro Zeile). Über die Größe bin ich mir noch nicht sicher.

Ich würde gerne wissen, ob ich auf Speicherprobleme stoßen würde, da ich die Datei mit FileWriter öffnen und dann weiter schreiben und schließlich die Datei schließen werde.

Sollte ich mir Gedanken über die Größe der Datei machen? Wenn ja, gibt es andere gute Techniken zum Schreiben in eine große Datei in Java als die Verwendung von FileWriter?

Wir verwenden Java 5.

java_mouse
quelle
Welche Java-Version verwenden Sie?
Martijn Verburg
Yo ... ich meine Nes. Verdammt, lass mich meinen magischen 8 Ball bekommen.
Abgerissen
Wenn es auf die Geschwindigkeit ankommt, versuchen Sie es mit einem wirklich großen Puffer (Multi-Megabyte). Es hat das Schreiben meiner Datei um den Faktor 10 beschleunigt. Natürlich können Ihre Ergebnisse variieren ...
RalphChapin

Antworten:

14

Nein, das solltest du nicht. Der Zweck einer Datei besteht darin, Dinge außerhalb des Direktzugriffsspeichers zu speichern. Die Größe des FileWriter ist konstant und unter allen Umständen ziemlich klein, selbst wenn es sich um einen gepufferten FileWriter handelt. Das ständige Umschreiben kann zu E / A-Auslastung oder CPU-Spitzen führen, aber mit ziemlicher Sicherheit nicht zu Speichermangel.

Kilian Foth
quelle
Ich dachte, die Dateidaten bleiben im Speicher, bis ich die Dateischreiberin schließe. Es sieht so aus, als ob meine Annahme falsch ist.
Java_Mouse
8
Nein, ein BufferedFileWriter speichert eine bestimmte Datenmenge im Speicher, aber diese Menge ist eine feste Menge, abhängig von der Umgebung, in der sie aufgerufen wird. Sie wächst nicht unbegrenzt mit der Anzahl der Bytes, die Sie durch sie drücken - das wäre eine Rezept für eine Katastrophe!
Kilian Foth
8

Wie Killian Foth es schrieb, sollten Sie überhaupt kein Problem haben, 60000 Zeilen sind überhaupt nicht so groß. Ich wollte Ihnen nur vorschlagen, einen der kostenlosen CSV-Parser zu verwenden, die hier im Rahmen der Initiative "Commons CSV" unter http://commons.apache.org/csv/ bereitgestellt werden, anstatt Ihre eigene Implementierung zu schreiben.

Ich habe Super CSV für einige Projekte verwendet und hatte sicherlich kein Problem damit.

Jalayn
quelle
1
Ich habe openCSV verwendet. Ich mag das. 60K Zeilen ist nichts. Mein alter Laptop verarbeitet das in einer Sekunde.
ahoffer
Schön, Jalayn zu hören! Wir haben gerade eine neue Version von Super CSV mit unzähligen Fehlerkorrekturen, neuen Funktionen und einer brandneuen Website veröffentlicht. Oh, und es ist jetzt in Maven Central :)
James Bassett
5

Verwenden Sie FileWriter nicht. Nicht aus Leistungsgründen (Javas E / A-Klassen speichern nicht alles im Speicher, aber 60.000 Zeilen sind auch dann nichts), sondern weil Sie die Zeichencodierung nicht auswählen können. Es wird implizit die Standardcodierung der Plattform verwendet, was bedeutet, dass Text außerhalb von ASCII beschädigt werden kann.

Verwenden Sie stattdessen einen OutputStreamWriter, der einen FileOutputStream umschließt. Oder noch besser eine CSV-Bibliothek, die all diese Probleme lösen sollte.

Michael Borgwardt
quelle
Oder verwenden Sie anstelle von OutputStreamWriter NIO-Klassen (FileChannel with ByteBuffers)? Behandeln alle CSV-Bibliotheken die Codierung? Ich habe mir SuperCSV kurz angesehen und nichts über den Umgang mit der Codierung gesehen.
Sam Goldberg
1
@ Sam Goldberg: Sie haben Recht, es scheint mit Reader / Writer zu funktionieren und diese Sorge dem Anrufer zu überlassen.
Michael Borgwardt
@MichaelBorgwardt Sie haben Recht - Super CSV wurde mit IoC geschrieben. Es liegt also an Ihnen, einen Reader / Writer bereitzustellen. Auf diese Weise können Sie in eine Datei, eine Zip-Datei, eine HTTP-Antwort usw. schreiben. Wir haben gerade eine neue Version veröffentlicht Version - bitte probieren Sie es aus :) Oh, und was die Zeichenkodierung betrifft, habe ich Joel Spolskys Artikel über Unicode immer als ausgezeichnet empfunden .
James Bassett
1

Sie könnten die Verwendung von BufferedWriter in Betracht ziehen, obwohl dies wahrscheinlich nicht wesentlich zur Leistung beiträgt. Dies ist auf jeden Fall eine bewährte Methode, da ich mir vorstelle, dass die Anzahl der Zeilen nicht immer 60.000 beträgt.

Haben Sie darüber nachgedacht, die Datei anschließend zu komprimieren? Wenn Sie beabsichtigen, viele dieser Dateien herumliegen zu lassen, ist es möglicherweise in Ihrem Interesse, sie nach dem Schreiben zu komprimieren, insbesondere wenn Sie diese Dateien alle paar Stunden einmal erstellen.

In Bezug auf den Speicher müssen Sie sich wahrscheinlich keine Sorgen machen, es sei denn, Sie arbeiten auf einem System mit sehr wenig Speicher. In diesem Fall sollten Sie BufferedWriter verwenden und die Puffergröße explizit festlegen.

Neil
quelle
1
Was ist ein BufferedFileWriter?
Michael Borgwardt
Hoppla. Ich meinte BufferedWriter. Fest.
Neil