BufferedInputStream - Negative Bytes.

Kai008

Erfahrenes Mitglied
Ich wollte mal versuchen, per BufferedInputStream eine Binärdatei lesen, und den Inhalt Hexadezimal ausgeben. Hab mir zum vergleichen Hexeditor besorgt. An sich fun st es ja recht gut, nur manchmal komme ich auf negative Zahlen, wobei dann irgend ein Mist wie z. B. "ffffff89" statt 89 rauskommt. Man könnte es sicher leicht verändern, aber es gibt sicher auch eine Möglichkeit wo ich nicht eingreifen muss.
Mir ist dann eingefallen, dass Byte ja Signed ist. Aber BufferedInputStream unterstützt nur Bytes, und 127/8 addieren hat nichts gebracht. Kann mir wer bitte sagen, wie ich die Zahlen auf rein positive Werte bekomme?

Java:
package core;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;

public final class Main extends Object
{
	public Main()
	{
		super();
	}
	public final static void main(String[] args)
	{
		Main.fileRead(1024);
	}
	private final static void fileRead(int bufferlenght)
	{
		BufferedInputStream in = null;
		try
		{
			in = new BufferedInputStream(
					new FileInputStream(
							new File("C:\\Neu Bitmap (7).PNG")));
			
			if(bufferlenght <= 0)
				bufferlenght = 1024;
			
			byte[] buffer = new byte[bufferlenght];
			while(in.read(buffer) > -1)
				for(int i = 0; i < buffer.length; i++)
					System.out.print(Integer.toHexString((int)buffer[i]).concat(" "));
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if(in == null)
				return;
			try
			{
				in.close();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}
}
 
Danke, jetzt funktioniert es. Allerdings ist mir aufgefallen, dass er nicht ganz zu Ende ließt. Zwar ist es relativ schwer zu sagen, wo genau er aufhört, weil gegen Ende des Files öfters die selben Werte vorkommen, und der Hexeditor bei einer zu langen Zahlenkolonne in der Suche nichts findet, aber er ließt spätestens die letzen 30 Bytes nicht. Ich bin jetzt auf die Idee gekommen, dass er vielleicht den Buffer im letzten Durchgang nur teilweiße füllt und dann das Ende erreicht/-1 zurückgibt, deshalb habe ich die for nochmal unter die while kopiert, hat aber nichts geändert bzw. er hat den letzten Teil ein 2. mal ausgegeben.

Kannst du mir btw. sagen, wie man das nennt, wie ich jetzt Bytes verwende? Also nichts als normale Zahlenvariablen, sondern eben das was das jetzt ist. ^^
Damit ich nach mehr Informationen darüber suchen kann, bzw. warum eine Vergleichsopperation das Ergebniss verändert. (Ist "&" ja, da Java kein Überladen unterstützt, oder? kA, hab nur darüber gelesen.)
 
Danke, jetzt funktioniert es. Allerdings ist mir aufgefallen, dass er nicht ganz zu Ende ließt.
Liest kommt von lesen. Es wird keinesfalls mit ß geschrieben. Das tut schon weh wenn man das liest ;)
Zwar ist es relativ schwer zu sagen, wo genau er aufhört, weil gegen Ende des Files öfters die selben Werte vorkommen, und der Hexeditor bei einer zu langen Zahlenkolonne in der Suche nichts findet, aber er ließt spätestens die letzen 30 Bytes nicht. Ich bin jetzt auf die Idee gekommen, dass er vielleicht den Buffer im letzten Durchgang nur teilweiße
Aua. teilweise
füllt und dann das Ende erreicht
In der Regel wird das so passieren, da selten die Dateigröße ein genaues Vielfaches der Puffergröße ist. Deshalb solltest du nicht den kompletten Puffer verarbeiten, sondern nur die Anzahl der Zeichen die auch wirklich gelesen wurden:
Java:
int readBytes;

while ((readBytes = in.read(buffer)) != -1) {
  for (int i = 0; i < readBytes; ++readBytes) {
    ...
  }
}
Kannst du mir btw. sagen, wie man das nennt, wie ich jetzt Bytes verwende? Also nichts als normale Zahlenvariablen, sondern eben das was das jetzt ist. ^^
Ich weiß nicht ob es dafür einen speziellen Namen gibt...
Damit ich nach mehr Informationen darüber suchen kann, bzw. warum eine Vergleichsopperation das Ergebniss verändert. (Ist "&" ja, da Java kein Überladen unterstützt, oder? kA, hab nur darüber gelesen.)
Das hat mit Überladen gar nichts zu tun. Und & ist auch kein Vergleichsoperator sondern der bitweise Und-Operator.

Gruß
 
Zuletzt bearbeitet:
Sorry wegen den vielen Fehlern. Das mit dem liest ist das selbe wie mit dem 3.-/4. Fall. (Mit dem auch auch teilweise Probleme habe.) Ich kenne die mir/mich bzw. halt dir/dich-Prüfung, denke aber selten daran. Mir bleibt nur der Trost, das ich im Vergleich zu vielen anderen online doch noch eine recht leserliche Schrift habe, und die Hoffnung, dass ich wenn ich das Wort das nächste schreibe an diesen Thread/deine Korrektur denke und es richtig mache. ^^
Aber man, ich habe sogar length falsch geschrieben. :rolleyes:

Habe "&" als Vergleichsoperator betrachtet, weil es ja in if's so wie "&&" wirkt, mit dem Unterschied, dass es auch die anderen Ergebnisse auswertet, auch wenn schon klar ist ob die insgesamte Operation true oder false sein wird.

Der Code führt nun zu einer Endlosschleife. Er gibt immer nur das erste Byte (89) aus. Ich habe read() gesagt, er soll bei Offset 0 anfangen.

Java:
private final static void fileRead(int bufferlength) throws Exception
{
	BufferedInputStream in =
		new BufferedInputStream(
			new FileInputStream(
					new File("C:\\Neu Bitmap (7).PNG")));
	if(bufferlength <= 0)
		bufferlength = 1024;
	int readBytes = 0;

	byte[] buffer = new byte[bufferlength];
	while((readBytes = in.read(buffer, 0, bufferlength)) != -1)
	{
		for(int i = 0; i < readBytes; ++readBytes)
		{
			String s = Integer.toHexString(0xff & (int)buffer[i]);
			if(s.length() == 1)
				s = "0".concat(s);
			System.out.print(s.concat(" "));
		}
	}
	in.close();
}
 
Habe "&" als Vergleichsoperator betrachtet, weil es ja in if's so wie "&&" wirkt, mit dem Unterschied, dass es auch die anderen Ergebnisse auswertet, auch wenn schon klar ist ob die insgesamte Operation true oder false sein wird.
Nein. Der &-Operator ist ein Bit-Operator, das hat mit true / false Auswertung oder Kurzschlußlogik nichts zu tun. Das Resultat des & Operators ist eine Zahl, kein Wahrheitswert.
Der Code führt nun zu einer Endlosschleife.
Ja, das stimmt. Die Schleife muss so aussehen:
Java:
for (int i = 0; i < readBytes; ++i) {
  ...
}
Gruß
 
Danke, es funktioniert.
Aber in "Java ist auch eine Insel" steht:

Nicht-Kurzschlussoperatoren

In einigen Fällen ist erwünscht, dass die Laufzeitumgebung alle Teilausdrücke auswertet. Das kann der Fall sein, wenn Funktionen Nebenwirkungen haben sollen, etwa Zustände ändern. Daher bietet Java zusätzlich die nicht über einen Kurzschluss arbeitenden Operatoren | und & an, die eine Auswertung aller Teilausdrücke erzwingen.

Beispiel In der ersten und dritten Anweisung wird die Methode boolean foo() nicht aufgerufen, in der zweiten und vierten schon.

System.out.println( true || foo() ); // true, foo() wird nicht aufgerufen
System.out.println( true | foo() ); // true, foo() wird aufgerufen
System.out.println( false && foo() ); // false, foo() wird nicht aufgerufen
System.out.println( false & foo() ); // false, foo() wird aufgerufen


Für Xor kann es keinen Kurzschlussoperator geben, da immer beide Operanden ausgewertet werden müssen, bevor das Ergebnis feststeht.
http://openbook.galileocomputing.de...02_005.htm#mjb7472917f33c38fb79c0baa79ca8a846
 
Zurück