Binärdateien auslesen (unsigned!)

Status
Nicht offen für weitere Antworten.

McFly81

Mitglied
Hallo

Ich schreibe momentan ein Programm das, grob gesagt, Binärdateien auslesen und darstellen soll. Das Auslesen wird aber für mich zum Problem (genauergesagt will/soll ich cd TAQ-Dateien der New Yorker Börser auslesen, in denen in einer (wie ich sagen möchte recht antiquierten Art und Weise^^) alle Transaktiondaten festgehalten werden).

Ein Beispiel: Ich will die Datei /home/chris/TAQ/Q200312B.BIN auslesen, diese hat eine record-Länge von 39 byte (ohne Zeilenende und Carriage Return). Die ersten 4 byte geben den Wert "QTIM" an.
Ein Zitat dazu aus dem Userguide: "Quote Time. This number reflects the time at which the quote entered CQS. Format: Cumulative number of seconds since midnight".
Problem 1, rein logisch: Wenn diese vier bytes die Anzahl der Sekunden seit Mitternacht angeben, ist das doch Verschwendung oder? Ein Tag hat 24*60*60=86,400 Sekunden. Diese Zahl ist in Binärschreibweise aber nur 17 bit lang, ließe sich also in 3 byte unterbringen statt 4!?
Problem 2: Wie lese ich diese Datei in Java aus? Nach meinen bisherigen Recherchen interpretiert Java Binärwerte grundsätzlich als vorzeichenbehaftet. Wie krieg ich das hin daß Java die bytes als vorzeichenlos betrachtet (Wert also zwischen 0 und 255, Werte wie -127 will ich nicht haben). Weiterhin muß ich Java ja klarmachen daß die 4 bytes zusammen eine Zahl ergeben, bisher betrachtet Java jedes byte als einzelne Zahl. Muß ich dafür extra Methoden schreiben oder gibt´s ne komfortable Abkürzung in Java?

Gruß, McFly

P.S. Hier ist ein kleines Testprogramm daß ich für das Problem geschrieben hab:

Code:
import java.io.FileInputStream;

public class Tester {
	
	public static void main(String[] args) {
		byte[] data = new byte[4];
		try {
			FileInputStream f = new FileInputStream("/home/chris/TAQ/Q200312B.BIN");
			f.read(data);
			for (int i=0; i<4; i++) {
				System.out.println(data[i]+127);
			}
			f.close();
		} catch (Exception ex) {
			System.out.println("mysterious.... hmm....");
		}
	}

}
 
So, das Prob mit den unsigned-Werten schein ich gelöst zu haben. Java scheint das doch zu können. Mit Brille wär das nicht passiert.^^

Code:
import java.io.FileInputStream;
import java.io.DataInputStream;

public class Tester {
	
    public static void main(String[] args) {
    	int[] data = new int[4];
    	try {
    		FileInputStream f = new FileInputStream("/home/chris/TAQ/Q200312B.BIN");
    		DataInputStream file = new DataInputStream(f);
    		for (int i=0; i<4; i++) {
    			data[i] = file.readUnsignedByte();
    			System.out.println(data[i]);
    		}
    		file.close();
    	} catch (Exception ex) {
    		System.out.println("mysterious.... hmm....");
    	}
    }

}

Bleibt nur noch die Verständnisfrage...
 
Zu deiner Verständnisfrage:
Da ich dir die Intention der Macher natürlich auch nicht sagen kann würde ich einfach mal vermuten das hier eine Integerzahl geschrieben wird. Integer sind nunmal 4 bytes lang. Aber mal ehrlich, wer kämpft den heutzutage noch um ein Byte mehr oder weniger :wink:
 
Naja, bei dieser "Datenbank" geht es um mehrere Dateien (5 DVDs mit jeweils 8 Dateien) die jeweils 1,3GB groß sind. Da würd´s vielleicht schon was ausmachen.^^

Also, es gibt readUnsignedShort und readUnsignedByte, aber kein readUnsignedInt. Ich hab jetze einfach
Code:
data = file.readInt()+2147483647;
gemacht, aber das ist doch bestimmt falsch oder?^^
 
Du kannst es als int einlesen und dann folgendermaßen unsigned machen:

Code:
int a1 = -1;
long a2 = (long)a1 & 0xFFFFFFFFL;    // =4294967295
 
byto: Zwei Dumme, ein Gedanke.^^ Ich hab mir folgende Klasse dazugeschrieben:

Code:
public class ClassDataInputStream extends java.io.DataInputStream {
	
	public ClassDataInputStream(java.io.InputStream in) {
		super(in);
	}
	
	public final long readUnsignedInt() throws java.io.IOException {
		//return (((long) readUnsignedShort()) << 16) | ((long) readUnsignedShort());
		return readInt() & 0xffffffffL;
	}

}
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben