FileInputStream bei Dateien > 4GB funktioniert unter Windows nicht

Hoschi01

Grünschnabel
Hi,
Hier das Coding:

Java:
public String ProcessMessage(File file, SapfschkMain main) {
	try {
//		int length = 1048576;
		int length = 4194304;
		int offset = 0;
		FileInputStream fin = new FileInputStream(file);
		BufferedInputStream bin = new BufferedInputStream(fin);
		
		MessageDigest md = MessageDigest.getInstance("MD5");
		StringBuffer buffer = new StringBuffer();
		while (true) {
		                int iBuf = bin.available();
			System.err.println(iBuf);
			if (iBuf < length) {
				length = iBuf;
			}
			byte[] result = new byte[length];
			bin.read(result, offset, length);
			md.update(result, offset, length);
			if (length == iBuf) {
				break;
			}
		}
		byte[] printTest = md.digest();
		for (int i = 0; i < printTest.length; i++) {
			String temp = Integer.toHexString(printTest[i]);
			if (temp.length() == 1) {
				temp = "0" + temp;
				buffer.append(temp);
			} else if (temp.length() > 2) {
				buffer.append(temp.substring(temp.length() - 2));
			} else
				buffer.append(temp);
		}
		bin.close();
		fin.close();
		return buffer.toString();
	} catch (NoSuchAlgorithmException e) {
		if (main != null) {
			main.addLog(e.getMessage());
		}
		return null;
	} catch (IOException e) {
		e.printStackTrace();
		return null;
	}
}
 
Zuletzt bearbeitet von einem Moderator:

zeja

Erfahrenes Mitglied
Du brichst das lesen aus dem Stream ja auch selber ab. In Zeile 14 weist du length iBuf zu, dass heißt length == iBuf. Somit verläßt du in Zeile 21 mit dem break die Schleife.

So gehts denke ich besser:
Java:
public String ProcessMessage(File file, SapfschkMain main) {
	final long fileLength = file.length();
	final int bufferSize = 1024;
	byte[] result = new byte[bufferSize];
	
	FileInputStream fin = null;
	BufferedInputStream bin = null;
	try {
		fin = new FileInputStream(file);
		bin = new BufferedInputStream(fin);

		MessageDigest md = MessageDigest.getInstance("MD5");
		while (true) {
			int bytesRead = bin.read(result, 0, bufferSize);
			if(bytesRead == -1){//Ende erreicht
				break;
			}
			
			md.update(result, 0, bytesRead);
		}
		
		StringBuffer buffer = new StringBuffer();
		byte[] printTest = md.digest();
		for (int i = 0; i < printTest.length; i++) {
			String temp = Integer.toHexString(printTest[i]);
			if (temp.length() == 1) {
				temp = "0" + temp;
				buffer.append(temp);
			} else if (temp.length() > 2) {
				buffer.append(temp.substring(temp.length() - 2));
			} else
				buffer.append(temp);
		}
		
		return buffer.toString();
	} catch (NoSuchAlgorithmException e) {
		if (main != null) {
			main.addLog(e.getMessage());
		}
		return null;
	} catch (IOException e) {
		e.printStackTrace();
		return null;
	}
	//Dieser Block wird sowohl nach einer Exception als auch im normalen
	//Ablauf ausgeführt
	finally{
		bin.close();
		fin.close();
	}
}

Denk bitte dran Methodennamen klein zu schreiben und das schließen von Streams im finally Block zu machen, damit diese geschlossen werden auch wenn eine Exception auftritt.

Weiterhin ist es unschön null zurückzugeben. Fällt dir da nichts sinnvolleres ein? Eventuell eine eigene Exception werfen?