OutOfMemoryError bei Verschlüsselungsalgorithmus

Endymion

Bekanntes Mitglied
Hi, ich habe heute Mittage ein kleines Verschlüsselungsprogramm geschrieben. Es verschlüsselt Dateien und Ordner, indem es sie zuerst zu einem Zip-File zusammenfasst, und danach mit einem Wort verschlüsselt. Das ganze geschieht über Datenströme. Bei kleineren Dateien und Ordnern funktioniert das auch alles. Wenn ich nun aber größere Ordner verschlüssele, bekomme ich einen OutOfMemoryError. So, das ganze passiert beim Zippen. Entweder liegt das an der Größe der einzelnen Dateien, oder daran, dass das ganze rekursiv passiert, das weiß ich nicht. Hat hier jemand ne Ahnung, was ich da machen kann? Folgender Code:
Java:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.util.Collections;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;

@SuppressWarnings("deprecation")
public class Coder {
	private final String codeword, mode;
	private final File src;
	private int pointer;
	private StringBuffer zipCode;

	public static void main(String[] args) {
		new Coder(args);
	}

	public Coder(String[] args) {
		testArgs(args);
		src = new File(args[0]);
		codeword = args[1];
		mode = args[2];
		switch (mode) {
		case "encode":
			encode();
			break;
		case "decode":
			decode();
		}
	}

	private void testArgs(String[] args) {
		if (args.length != 3) {
			exit("Illegal arguments.\nUse an direct url to an existing file as the first,\nan codeword as the second,\nand the string \"encode\" or \"decode\"\nto encode or decode the file as the third parameter.\nSystem will exit now.");
		}
		if (!(new File(args[0]).exists())) {
			exit("The source file does not exist.\nSystem will exit now");
		}
		if (!(args[2].equals("encode") || args[2].equals("decode"))) {
			exit("Invalid mode String.\nUse \"encode\" or \"decode\" to select the mode.\nSystem will exit now.");
		}
	}

	private void exit(String error) {
		System.err.println(error);
		System.exit(0);
	}

	private void encode() {
		System.out.printf("Started encoding %s with the codeword %s%n",
				src.getAbsolutePath(), codeword);
		zipCode = new StringBuffer();
		ZipOutputStream zipOutputStream;
		zipFile(new File[] { src }, zipOutputStream = new ZipOutputStream(
				new StringBufferOutputStream(zipCode)));
		try {
			zipOutputStream.close();
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
		pointer = 0;
		BufferedInputStream inputStream = new BufferedInputStream(
				new StringBufferInputStream(zipCode.toString()));
		byte[] buffer = new byte[8192];
		File dest = new File(src.getAbsolutePath() + ".coded");
		try {
			BufferedOutputStream outputStream = new BufferedOutputStream(
					new FileOutputStream(dest));
			System.out.println("Started encoding compressed File");
			for (int len; (len = inputStream.read(buffer)) != -1;) {
				buffer = codeChars(buffer, len);
				outputStream.write(buffer, 0, len);
			}
			System.out.printf("Finished encoding %s%n", src.getAbsolutePath());
			outputStream.flush();
			inputStream.close();
			outputStream.close();
		} catch (FileNotFoundException e) {
			System.err.println(e.getMessage());
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
	}

	private void decode() {
		if (!src.getAbsolutePath()
				.substring(src.getAbsolutePath().length() - 5).equals("coded")) {
			exit("Invalid source file.\nUse an direct URL to an .coded-file.\nSystem will exit now");
		}
		try {
			System.out.printf("Started decoding %s with the codeword %s%n",
					src.getAbsolutePath(), codeword);
			zipCode = new StringBuffer();
			BufferedInputStream inputStream = new BufferedInputStream(
					new FileInputStream(src));
			BufferedOutputStream outputStream = new BufferedOutputStream(
					new StringBufferOutputStream(zipCode));
			byte[] buffer = new byte[8192];
			pointer = 0;
			System.out.println("Started decoding compressed file");
			for (int len; (len = inputStream.read(buffer)) != -1;) {
				buffer = decodeChars(buffer, len);
				outputStream.write(buffer, 0, len);
			}
			System.out.println("Finished decoding compressed file");
			outputStream.flush();
			inputStream.close();
			outputStream.close();
		} catch (FileNotFoundException e) {
			System.err.println(e.getMessage());
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
		unzipFile(zipCode);
	}

	private void zipFile(File[] files, ZipOutputStream zipOutputStream) {
		for (File file : files) {
			System.out.printf(
					"Started including file %s to the compressed file%n",
					file.getName());
			if (!file.isDirectory()) {
				try {
					byte[] buffer = new byte[8192];
					BufferedInputStream inputStream = new BufferedInputStream(
							new FileInputStream(file));
					String relativePath = file.getAbsolutePath().substring(
							file.getParent().length());
					zipOutputStream.putNextEntry(new ZipEntry(relativePath));
					for (int len; (len = inputStream.read(buffer)) != -1;) {
						zipOutputStream.write(buffer, 0, len);
					}
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				zipFile(file.listFiles(), zipOutputStream);
			}
			try {
				zipOutputStream.closeEntry();
			} catch (IOException e) {
				System.err.println(e.getMessage());
			}
			System.out.printf(
					"Finished including file %s to the compressed file%n",
					file.getName());
		}
	}

	private byte[] codeChars(byte[] chars, int len) {
		for (int i = 0; i < len; i++) {
			chars[i] = (byte) ((chars[i] + codeword.charAt(pointer)) % Character.MAX_VALUE);
			if (++pointer == codeword.length()) {
				pointer = 0;
			}
		}
		return chars;
	}

	private byte[] decodeChars(byte[] chars, int len) {
		for (int i = 0; i < len; i++) {
			char value = (char) (chars[i] - codeword.charAt(pointer));
			if (value < 0) {
				value = (char) (Character.MAX_VALUE + value);
			}
			chars[i] = (byte) value;
			if (++pointer == codeword.length()) {
				pointer = 0;
			}
		}
		return chars;
	}

	private void unzipFile(StringBuffer sb) {
		try {
			System.out.println("Started writing temporary file");
			File file = File.createTempFile("zip", null);
			file.deleteOnExit();
			BufferedInputStream inputStream = new BufferedInputStream(
					new StringBufferInputStream(zipCode.toString()));
			BufferedOutputStream outputStream = new BufferedOutputStream(
					new FileOutputStream(file));
			byte[] buffer = new byte[8192];
			for (int len; (len = inputStream.read(buffer)) != -1;) {
				outputStream.write(buffer, 0, len);
			}
			outputStream.flush();
			inputStream.close();
			outputStream.close();
			inputStream = null;
			outputStream = null;
			buffer = null;
			System.out.println("Finished writing temporary file");
			ZipFile zipFile = new ZipFile(file);
			for (ZipEntry entry : Collections.list(zipFile.entries())) {
				System.out
						.printf("Started extracting file %s from the compressed file%n",
								entry.getName());
				File entryFile = new File(src.getParent(), entry.getName());
				if (entry.isDirectory()) {
					entryFile.mkdirs();
				} else {
					new File(entryFile.getParent()).mkdirs();
					inputStream = new BufferedInputStream(
							zipFile.getInputStream(entry));
					outputStream = new BufferedOutputStream(
							new FileOutputStream(src.getAbsolutePath()
									.substring(0,
											src.getAbsolutePath().length() - 6)));
					buffer = new byte[8192];
					for (int len; (len = inputStream.read(buffer)) != -1;) {
						outputStream.write(buffer, 0, len);
					}
				}
				outputStream.flush();
				inputStream.close();
				outputStream.close();
				zipFile.close();
				System.out
						.printf("Finished extracting file %s from the compressed file%n",
								entry.getName());
			}
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
	}
}
 

Marco13

Top Contributor
Ja, was heißt "größer"? Standardmäßig kriegt die JVM nicht so viel Speicher. Starte mal mit
java -Xmx1000m DasProgramm
für 1000MB Speicher.
 
S

Spacerat

Gast
Also was da schief läuft wird sich wohl nur schwer nachvollziehen lassen, weil die Rekursion recht undurchsichtig ist. So einen Knoten löst man, wenn man anfängt unübersichtlichen Code in immer kürzer werdende Methoden auslagert. Dabei stellt man dann auch fest, wo man sog. ObjectReusing anwenden kann statt 1000 neue Objekte zu instanzieren um sie im nächsten Aufruf wieder zu verwerfen. Damit würde man u.U. den GC entlasten, wenn er mit dem Wegräumen der verworfenen Objekte nicht mehr nachkommt.
 
Zuletzt bearbeitet von einem Moderator:

Endymion

Bekanntes Mitglied
Das -Xlx1000m hat selbst bei -Xlx7000m nur bis zu ner bestimmten Größe geholfen.. Aber ich hab den Fehler gefunden: Ich habe den Code vom ZipFile in einem StringBuffer anstatt in einem .tempFile gespeichert, deshalb hat das Programm so viel Arbeitsspeicher gefressen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Apache fop - OutOfMemoryError Allgemeine Java-Themen 10
L Java OutOfMemoryError Java heap space Allgemeine Java-Themen 3
B OutOfMemoryError kommt nicht/Bug in Java? Allgemeine Java-Themen 2
Maxim6394 OutOfMemoryError nicht nachvollziehbar Allgemeine Java-Themen 8
reibi OutOfMemoryError bei Behandlung von BufferedImage's Allgemeine Java-Themen 6
L java.lang.OutOfMemoryError: Java heap space Allgemeine Java-Themen 10
H java.lang.OutOfMemoryError bei der wiederholten Erzeugng von Threads Allgemeine Java-Themen 8
D OutOfMemoryError:Java hep space Allgemeine Java-Themen 7
M OutOfMemoryError in nebenläufigen Threads Allgemeine Java-Themen 6
C nach ca. 1 Stunde OutOfMemoryError Allgemeine Java-Themen 15
Shoox OutOfMemoryError Allgemeine Java-Themen 10
J Crawler selbst geschreiben: OutOfMemoryError Allgemeine Java-Themen 14
A OutOfMemoryError: Java heap space Allgemeine Java-Themen 11
K OutOfMemoryError: Java heap space troz -Xms1024m Allgemeine Java-Themen 2
P OutOfMemoryError beim XML erstellen bzw parsen, mehr RAM? Allgemeine Java-Themen 4
R OutofMemoryError bei CharArraywriter Allgemeine Java-Themen 5
F OutOfMemoryError: Java heap space - Speicher verändern Allgemeine Java-Themen 8
J java Thread java.lang.OutOfMemoryError: Java heap space Allgemeine Java-Themen 7
B OutOfMemoryError und Arraylisten Allgemeine Java-Themen 2
G Error: java.lang.OutOfMemoryError: Java heap space Allgemeine Java-Themen 2
S java.lang.OutOfMemoryError: Java Allgemeine Java-Themen 22
M java.lang.OutOfMemoryError Allgemeine Java-Themen 2
F java.lang.OutOfMemoryError: Java heap space Allgemeine Java-Themen 22
S fehlermeldung java.lang.OutOfMemoryError Allgemeine Java-Themen 5
G outOfMemoryError beim Einlesen einer Datei abfangen? Allgemeine Java-Themen 13
H Skalieren von Image -> java.lang.OutOfMemoryError - WARUM Allgemeine Java-Themen 18
G jTable-Problem --> java.lang.OutOfMemoryError Allgemeine Java-Themen 5
F java.lang.OutOfMemoryError Allgemeine Java-Themen 13
C OutOfMemoryError lokalisieren Allgemeine Java-Themen 9
M java.lang.OutOfMemoryError Allgemeine Java-Themen 7
T jva.lang.OutOfMemoryError Allgemeine Java-Themen 8
F java.lang.OutOfMemoryError Allgemeine Java-Themen 17

Ähnliche Java Themen

Neue Themen


Oben