2017-05-28 4 views
1

Ich habe Beziehung, wo es für jeden Datensatz BYTEA Spalt (UTF-8) -Codierung 3 Zahlen in der folgenden Reihenfolge ist:JAVA JDBC-Treiber PostgreSQL: parse Zahlen als BYTEA Objekt codierte

Bytes 0-1: Nummer 1

Bytes 2-3: Nummer 2

Bytes 4-6: Nummer 3

Wie kann ich die binären Daten zu lesbaren Zahlen analysieren?

Zur Zeit habe ich diese und nicht wissen, wie es weitergeht:

Class.forName(dbDriver); 
Connection connection = DriverManager.getConnection(dbUrl, dbUser, dbPass); 
Statement st = connection.createStatement(); 
String query = "SELECT ..."; 
ResultSet rs = st.executeQuery(query); 
while (rs.next()) { 
    byte[] data = rs.getBytes(1); 
    //TODO Parse 
} 

Danke,

+1

Sie scheinen Byte 4 zweimal zu verwenden. Ich nahm an, dass das ein Tippfehler ist, und diese Nummer 3 ist von Bytes 5-6, nicht 4-6, d. H. 2 Bytes lang, gleich wie Nummer 1 und 2. – Andreas

+0

@Andreas Hallo, mein Fehler. Ich habe bearbeitet. die ersten 2 sind 2 Bytes, die dritte ist 3 Bytes und kann negativ sein. – michael

+1

Wenn nur die dritte Zahl negativ sein kann, müssen Sie das Zahlenformat wirklich besser definieren. Z.B. Sind die Zahlen in Binärform gespeichert? Wenn ja, sind vorzeichenbehaftete Nummern in [Zweierkomplement] gespeichert (https://en.wikipedia.org/wiki/Two%27s_complement)? Oder wird das Zeichen selbst als Byte gespeichert? Wenn nicht binär, sind die Zahlen als Text gespeichert? Oder [BCD] (https://en.wikipedia.org/wiki/Binary-coded_decimal) (gepackt oder ausgepackt)? Oder etwas anderes? – Andreas

Antwort

2

Das hängt davon ab, wie die Nummern gespeichert sind.
Sind sie binär?
Sind sie signed?
Sind sie groß oder klein? endian?

Angenommen, ja zu den ersten beiden, können Sie Bit-Manipulation, z.

// Little-endian 
short num1 = (short) ((data[0] & 0xFF) | (data[1] & 0xFF) << 8); 

// Big-endian 
short num1 = (short) ((data[0] & 0xFF) << 8 | (data[1] & 0xFF)); 

Aber es ist wahrscheinlich einfacher ByteBuffer zu verwenden:

ByteBuffer buf = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); 
short num1 = buf.getShort(); 
short num2 = buf.getShort(); 
short num3 = buf.getShort(); 

ByteBuffer ist BIG_ENDIAN standardmäßig.

+0

mit ByteBuffer, wo ich angeben, dass die ersten 2 Zahlen besteht aus 2 Bytes und die dritte aus 3? Auch die Zahlen können negativ sein, ist es wichtig? – michael

+1

'ByteBuffer' hat keine Methode, um 3 Bytes als Zahl zu erhalten. Es kann 1 ('get()'), 2 ('getShort()'), 4 ('getInt()') oder 8 ('getLong()'), alle als vorzeichenbehaftete Zweierkomplement-Binärzahlen entschlüsselt werden * ("signiert" bedeutet, dass der Wert negativ sein kann) *. Wenn Sie eine 3-Byte-Nummer benötigen, verwenden Sie Bit-Manipulation, aber ich bezweifle, dass Sie tun (siehe [mein Kommentar] (https://stackoverflow.com/questions/44227220/java-jdbc-driver-postgresql-parse-numbers-) coded-as-bytea-object/44227352? noredirekt = 1 # comment75465770_44227220)). – Andreas

0

Können Sie dies versuchen:

Für String:

String tatto = "my tatto"; //for example 
    byte[] array = tatto.getBytes(); // Or any bytes 
    String s = new String(array); 
    System.out.println(s); 

Für byte []:

byte[] data = new byte[]{ 1, 16, 84, 2, 101, 110, 83, 111}; 
    long val = 0; 
    for (int i = 0; i < data.length; i++) 
    { 
     val = (val << 8) + (data[i] & 0xff); 
    } 
    System.out.println(val); 
+0

Hallo ich bekomme java.lang.NumberFormatException.forInputString – michael

+0

Aufruf 'toString()' auf einem 'byte []' wird etwas wie '[B @ 15db9742'. – Andreas

+0

Das ist richtig, Sie erhalten Byte [] von db, aber wir wissen nicht, welche Art von Daten vor dem Speichern. –