Stream unvollständig

Status
Nicht offen für weitere Antworten.

okel

Neues Mitglied
Hallo,

ich versuche, Daten (XML) zu zippen und dann zu encrypten (DES). Leider wird der Stream nicht immer vollständig geschrieben. Hier ist der Code:

Code:
	public boolean write(PersistentData persistentData) throws StorageException {
		try {
			FileOutputStream fileOutputStream = new FileOutputStream(new File(fileName));
			writeToStream(persistentData, fileOutputStream);
			fileOutputStream.close();
			
			return true;
		} catch (FileNotFoundException ex) {
			throw new StorageException(ex);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		
		return false;
	}

	protected void writeToStream(PersistentData persistentData, final OutputStream stream) throws IOException {
		OutputStream outputStream = null;
		
		final PipedInputStream pipedInputStream = new PipedInputStream();
		outputStream = new PipedOutputStream(pipedInputStream);
		new Thread() {
			public void run() {
				encrypter.encrypt(pipedInputStream, stream);
				try {
					pipedInputStream.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}.start();
		
		ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
		zipOutputStream.setLevel(zipLevel);
		
		zipOutputStream.putNextEntry(new ZipEntry("meta"));
		zipOutputStream.write(Long.toString(System.currentTimeMillis()).getBytes());
		
		zipOutputStream.putNextEntry(new ZipEntry("data"));
		Model model = persistentData.getModel();
		XmlWriter.write(zipOutputStream, model.getData());
		
		zipOutputStream.closeEntry();
		zipOutputStream.close();

		outputStream.close();
	}

Zunächst mal bin ich mir nicht sicher, ob mein Konstrukt mit dem Thread sinnvoll ist, aber nur so ist mein Programm nicht einfach stehen geblieben, denn die encrypt-Methode und das XmlWriter.write müssen ja gleichzeitig laufen, oder?

Mein eigentliches Problem ist aber, dass die Dateilänge nach dem Schreiben gerne mal kleiner ist als gewünscht, was dann natürlich zu Datenverlust führt. Manchmal sind es nur ein paar Byte, manchmal aber bis zu ca. 100 Byte (Soll: ~257 kByte). Ich habe auch schon diverse flush-Aufrufe eingebaut, aber geholfen hat es nicht.

Ich verwende jdk1.6.0_07 unter Linux.

Grüße

Stefan


Edit: Eigentlich sollte der Titel "Encrypteter gezippter FileOutputStream unvollständig" heißen, aber das geht aus "Spamschutzgründen" nicht.
 
okel hat gesagt.:
ich versuche, Daten (XML) zu zippen und dann zu encrypten (DES). Leider wird der Stream nicht immer vollständig geschrieben.
Ich bin nicht sicher, aber das könnte eine Spur sein:
Ein Block-Cipher operiert auf Datenblöcken. Man muss sicherstellen,
daß die Datenlänge ein Blockvielfaches ist (padding schemes).
 
evtl encrypter.flush()/close() aufrufen? was auch immer für eine klasse hinter encrypter steckt
 
Die Abhängigkeit von der Datenlänge möchte ich mal nicht annehmen, denn (da hatte ich mich nicht klar ausgedrückt) die unterschiedliche Länge dessen, was in die Datei geschrieben wird, habe ich bei jeweils exakt gleiche Daten. Ich rufe mehrmals write(...) auf und erhalte jeweils ein anderes Ergebnis.

Den Encrypter habe ich an ein Beispiel aus dem Internet angelehnt, die encrypt()-Methode lautet
Code:
	public void encrypt(InputStream in, OutputStream out) {
		try {
			out = new CipherOutputStream(out, ecipher);

			int read = 0;
			while ((read = in.read(buf)) >= 0)
				out.write(buf, 0, read);
			
			out.close();
		} catch (java.io.IOException e) {
		}
	}

Ich bin inzwischen etwas schlauer, denn im abgekupferten Beispiel wird dummerweise eine java.io.IOException ignoriert. Und die fliegt natürlich prompt, wenn die Dateilänge zu klein ist.
Code:
java.io.IOException: Ungültiger Dateideskriptor
	at java.io.FileOutputStream.writeBytes(Native Method)
	at java.io.FileOutputStream.write(FileOutputStream.java:247)
	at javax.crypto.CipherOutputStream.write(DashoA13*..)
	at xasche.persist.DesEncrypter.encrypt(DesEncrypter.java:63)
	at xasche.persist.AbstractStorage$3.run(AbstractStorage.java:153)

Wenn jemand weiß, was mit meinem Dateideskriptor falsch sein könnte, ... Ich hab ein paar Hinweise auf java-Bugs in Dateioperationen gefunden, die aber alle eigentlich nur unter anderen Bedingungen auftreten.

Stefan
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben