# Umwandlung ByteArrayOutputStream in InputStream



## M8 (10. Mai 2012)

Hallo, ich habe folgendes Problem

vor einiger Zeit habe ich einen Entzipper für TGZ Dateien geschrieben, der so aussah, dass ich zuerst die tgz-Datei auf 
Platte abgelegt habe, dann diese ausgelesen, uncompressed und als tar-Datei wieder auf Platte abgelegt, dann die tar-Datei ausgelesen wieder uncompressed und an den Zielort gespeichert
anschließend hab ich die tgz und tar Datei gelöscht

jetzt möchte ich es so machen, dass ich die beiden Zwischendateien garnicht habe sondern die Inhalte über die Streams im Speicher halte

aktuell habe ich es so, dass ich das tgz-file nicht abspeichere, sondern das byte[] direkt in die methode liefere, das tarFile wird dann nochmal abgelegt, ausgelesen und wieder abgespeichert
aber eigentlich soll auch das nicht mehr passieren

aktuelle Lösung:
(nicht auf das exceptionhandling achten, hab das fast ganz gelöscht der übersicht halber)


```
private String extractArchive(byte[] documentTGZ, String destinationPfad, String suchString) {
		int BUFFER = 2048;

		try {
			// ***Entpacken TGZ und Speichern TAR**********************

			// TAR-Archiv in TEMP ablegen
			
			String tarPfad = TEMPDIR + "\\"
					+ GzipUtils.getUncompressedFilename("file");
			File tar = new File(tarPfad);
			OutputStream out = new FileOutputStream(tar);
			
			InputStream is = new ByteArrayInputStream(documentTGZ);
			CompressorInputStream cis = new CompressorStreamFactory()
					.createCompressorInputStream("gz", is);

			// Wegschreiben des TAR-Archivs
			final byte[] buffer = new byte[BUFFER];
			int n = 0;
			while (-1 != (n = cis.read(buffer))) {
				out.write(buffer, 0, n);
			}
			logger.debug("TarFile weggeschrieben");
			out.close();
			is.close();
			cis.close();

			// **********Entpacken TAR und Speichern der beinhalteten Dateien******

			InputStream ins = new FileInputStream(tar);
			ArchiveInputStream in = new ArchiveStreamFactory()
					.createArchiveInputStream("tar", ins);
			TarArchiveEntry entry;

			while ((entry = (TarArchiveEntry) in.getNextEntry()) != null) {

				if (entry.isDirectory()) {
					// Hauptverzeichnis ablegen, restliche Verzeichnise darunter 
                                        // entsprechend der Struktur

					File verzeichnis = new File(destinationPfad + File.separatorChar
							+ entry.getName());
					verzeichnis.mkdirs();
				} else {

					OutputStream outs = new FileOutputStream(destinationPfad
							+ File.separatorChar + entry.getName());
					org.apache.commons.compress.utils.IOUtils.copy(in, outs);
					outs.close();
				}
			}
			logger.debug("TarFile entpackt");
			ins.close();
			in.close();
			tar.delete();

		} catch (DiverseExceptions ex) {
			throw new Exception(
					"Fehler");
		
		return destinationPfad;
	}
```

ich habe es auch einmal versucht das tarFile auch in einem Stream zu halten, es wird dann auch entpackt, also alle entries sind richtig vorhanden, aber es ist kein Inhalt darin, ich habe also leere PDF-Dateien am Ende
hat jemand eine Idee wie ich das lösen kann ohne temporär ein file abzulegen?

```
private String extractArchive(byte[] documentTGZ, String destinationPfad, String suchString) {
		int BUFFER = 2048;

		try {
			// *******Entpacken TGZ und Rüberreichen in TAR***************
	
			OutputStream out = new ByteArrayOutputStream();
			
			InputStream is = new ByteArrayInputStream(documentTGZ);
			CompressorInputStream cis = new CompressorStreamFactory()
					.createCompressorInputStream("gz", is);

			// Wegschreiben des tarInhalts in OutputStream
			final byte[] buffer = new byte[BUFFER];
			int n = 0;
			if(buffer==null) {
				throw Exception("Fehler");
			}
			while (-1 != (n = cis.read(buffer))) {
				out.write(buffer, 0, n);
			}
			logger.debug("Stream mit Inhalt tarFile erstellt");
			out.close();
			is.close();
			cis.close();


			// *******Entpacken TAR und Speichern der beinhalteten Dateien**********
			
			InputStream ins = new ByteArrayInputStream(out.toString().getBytes());
			ArchiveInputStream in = new ArchiveStreamFactory()
					.createArchiveInputStream("tar", ins);
			TarArchiveEntry entry;

			//  bei Verzeichnis >> erstellen, bei Dateien >> abspeichern

			while ((entry = (TarArchiveEntry) in.getNextEntry()) != null) {

				if (entry.isDirectory()) {
					// Hauptverzeichnis ablegen,
					// restliche Verzeichnise darunter entsprechend der Struktur
	
					File verzeichnis = new File(destinationPfad + File.separatorChar
							+ entry.getName());
					verzeichnis.mkdirs();
				} else {

					OutputStream outs = new FileOutputStream(destinationPfad
							+ File.separatorChar + entry.getName());
					org.apache.commons.compress.utils.IOUtils.copy(in, outs);
					outs.close();
				}
			}
			logger.debug("TarFile entpackt");
			ins.close();
			in.close();
			tar.delete();


		} catch (DiverseExceptions ex) {
			throw new Exception("Fehler");
		} 
		return destinationPfad;
	}
```


wie gesagt nur habe ich das Problem, dass in meinen entpackten Dateien kein Inhalt mehr ist...
ich hoffe jemand hat ne Idee wie das funktionieren kann!
Danke schonmal


----------



## irgendjemand (10. Mai 2012)

hmm ... TAR wird glaube ich von java nicht native unterstützt ... aber GZIP auf jeden fall -> java.util.zip.* ...

das ganze on-the-fly ... hmm ... sollte eigentlich auch funktionieren wenn du die variante die mit den temp-daten auf der platte arbeitet durch ByteArray*Stream ersetzt ... in wie weit du da aber mit speicher-problemen zu kämpfen haben wirst lässt sich so nicht sagen ... würde aber mal grob 2 x TGZ oder mehr annehmen ...

von apache commons bin ich kein freund und kann daher nicht dierekt helfen ... wäre besser wenn du ZIP oder nur GZip als ausgangsformat hättest ... das kann java native ..

*TAR unterscheidet sich leider von ZIP ... auch wenn TAR in dem sinne nur das zusammenpacken von vielen daten in eine container-datei darstellt und damit ZIP ohne kompression gleichkommen würde ... aber die formate sind anders ... sollte auf jeden fall mal bei Sun/Oracle gemeldet werden das das native in java implementiert wird*


----------



## M8 (10. Mai 2012)

@irgendjemand:

hmm irgendwie hat mir dein Eintrag nicht weitergeholfen...dass es einfacher wär wenn ich zip-Archive hätte hab ich schon gewusst als ich den Entzipper geschrieben hab, aber das steht nunmal nicht zur Debatte...
ich bekomme tgz-Dateien und muss damit umgehen können

und ja ich weiß, dass es eigentlich auch funktionieren sollte wenn ich ByteArrayStreams benutze nur das tut es gerade nicht und ich weiß nicht warum deswegen hab ich ja meine frage gepostet

ich könnte mich ja mal bei sun/oracle bewerben und ihnen anbieten das native zu implementieren ^^


----------



## SlaterB (10. Mai 2012)

out.toString() für ByteArrayOutputStream ist doch glatter Irrsinn, was soll das denn?
gibt auch ne Methode toByteArray() in ByteArrayOutputStream,

müsste eigentlich der Fehler sein, siehe auch Testprogramm unten, aber wenn du dennoch alle Dateinamen erhälst, bin ich minimal skeptisch

dass du diesen offensichtlichen Fehler nicht selbst gefunden hast, erlaubt mir dennoch die drastische Ausdrucksweise am Anfang,
du codest so komplizierte Sachen, da denkst du nicht daran, das wichtige byte[] als Zwischenschritt mit einer Datei auf der Festplatte zu vergleichen?


```
public class Test {
    public static void main(String[] args) throws Exception  {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        out.write(-44);
        out.write(5);
        out.write(6);
        out.write(5);
        out.write(4);
        System.out.println(out.toString());
        System.out.println(Arrays.toString(out.toString().getBytes()));
        System.out.println(Arrays.toString(out.toByteArray()));
    }
}
```


----------



## M8 (10. Mai 2012)

@SlaterB

ja bei mir hat das "out." die Methode toByteArray() nicht angeboten weil ich das so instanziiert hatte

```
OutputStream out = new ByteArrayOutputStream();
```
 
cool danke für den Hinweis...jetzt gehts =)))
das mit dem "codest so komplizierte Sachen" fass ich mal als Kompliment auf ^^


----------



## SlaterB (10. Mai 2012)

dass du ByteArrayOutputStream so wie er ist verwenden musst ist eine Selbstverständlichkeit,
als weiteres Lob nicht extra erwähnt 

dass du es erwähnst und gar als Grund angibst warum du die Methode nicht verwenden wolltes oder gar nicht kennst/ nachgeschaut hast,
trübt das Bild wiederum,
aber genug dieser Spielereien


----------

