Zeilennummer in OutputStream einfügen

blindmind

Mitglied
Hallo Zusammen!
Sitze gerade an neuer Aufgabe ner Freundin. Es soll einfach nur eine gegebene Datei kopiert werden. Nicht sonderlich spannend, erstes Fachsemester...
Mein Problem ist, das in die "Destination"-Datei zusätzlich noch am Anfang einer jeden Zeile stehen soll. Und genau da stehe ich auf dem Schlauch...

Hier der Code:

Code:
...
try {
			in = new FileInputStream(sourceFile);
			out = new FileOutputStream(destinationFile);
			byte[] buf = new byte[1024];
		    int len;
		    //int lineCount = 1;
		    while ((len = in.read(buf)) != -1) {
		        out.write(buf, 0, len);
		    }
		    in.close();
		    out.close();
		    System.out.print("Datei erfolgreich kopiert.");
...

Ach, es sollen wirklich Bytes verarbeitet werden, ich glaube zeilenweise würde es mit Printwriter gehen..Aber in dem Fall schlecht...
Danke für Eure Hilfe!
M.
 

Fabio Hellmann

Erfahrenes Mitglied
Hi,
eine Datei umzukopieren ist in der Tat nicht schwer. Allerdings verstehe ich nicht, warum du das mit den Zeilennummern auf byte-Ebene machst (Vorgabe?). Einfacher würde es auf String-Ebene gehen.
Java:
		BufferedReader reader = null;
		BufferedWriter writer = null;
		try {
			reader = new BufferedReader(new FileReader(input));
			writer = new BufferedWriter(new FileWriter(output));
			
			String line;
			int lineCount = 1;
			while((line = reader.readLine()) != null) {
				writer.write(lineCount + "\t" + line);
				writer.newLine();
				lineCount++;
			}
			writer.flush();
		} finally {
			reader.close();
			writer.close();
		}

Natürlich geht das auch in byte-Ebene, allerdings sieht die Lösung dann nicht mehr ganz so schön und übersichtlich aus.
Java:
		FileInputStream in = null;
		FileOutputStream out = null;
		try {
			in = new FileInputStream(input);
			out = new FileOutputStream(output);
			
			final byte[] buf = new byte[1024];
			int len;
			int lineCount = 1;
			
			while((len = in.read(buf)) != -1) {
				final String s = new String(buf, 0, len);
				final StringBuilder result = new StringBuilder();
				
				if(lineCount == 1) {
					result.append(lineCount + "\t");
				}
				
				final String[] split = s.split("\n");
				for(final String string : split) {
					lineCount++;
					result.append(string + "\n" + lineCount + "\t");
				}
				out.write(result.toString().getBytes());
			}
		} finally {
			in.close();
			out.close();
		}

Exceptions musst du noch abfangen. Die habe ich zur Übersicht weggelassen.

Gruß

Fabio
 

slowfly

Erfahrenes Mitglied
Wie gross ist denn das File und wieviel Heap darf die Applikation haben?

Wenn's nur paar kilobyte-Files sind, hätte ich es eingelesen und replaceAll("\n","\nDestination") gemacht (in den Tipps gibt's irgendwo nen Beitrag, wie man Files in einem Einzeiler einlesen kann).

Bei grossen Files hätt ich's mit nem LineNumberReader gemacht: Da bekommste die einzelnen Zeilen, wenn du sie ins neue File schreibst einfach noch "\nblabla" vor die Zeile setzen.

Wichtig bei Writern und Reader: Charsets. Ich hasse Charsets auch, aber vor Allem bei solchen Datei-einlese-kopierereien kann es ganz Wüste Ergebnisse geben.

Klugsch***-Modus:eek:n
Bitte die streams im finally-catch closen, weil, wenn du in einem Serverumfeld bist, die Ressourcen offen bleiben. Und wenn ihr Lehrer sagt, das sei jetzt nicht so wichtig: Bitte ins Gesicht Round-House-Kicken, kthxbye ;P - ne, im Ernst, solche "Fehler" können sehr hässlich werden, und meist muss nicht der Entwickler morgens um drei Aufstehen und ein System analysieren, weil es zu langsam ist.

Gruss
slowy