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());
}
}
}