2017-05-28 1 views
1

je relation où pour chaque enregistrement il y a colonne de BYTEA (UTF-8) codant pour 3 nombres dans l'ordre suivant:JAVA pilote JDBC PostgreSQL: Parse nombres codés comme objet BYTEA

octets 0-1: numéro 1

octets 2-3: numéro 2

octets 4-6: numéro 3

Comment puis-je analyser les données binaires vers des numéros lisibles?

Actuellement, j'ai cela et ne sais pas comment continuer:

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 
} 

Merci,

+1

Vous semblez utiliser l'octet 4 deux fois. J'ai supposé que c'est une faute de frappe, et ce nombre 3 est des octets 5-6, pas 4-6, c'est-à-dire 2 octets de long, même que le numéro 1 et 2. – Andreas

+0

@Andreas Salut, mon erreur. J'ai édité. les 2 premiers sont 2 octets, le troisième est 3 octets et peut être négatif. – michael

+1

Si seulement le troisième nombre peut être négatif, alors vous devez vraiment mieux définir le format numérique. Par exemple. sont les nombres stockés en binaire? Si oui, les numéros signés sont-ils stockés dans [complément à deux] (https://en.wikipedia.org/wiki/Two%27s_complement)? Ou est le signe stocké comme un octet par lui-même? Si ce n'est pas binaire, les numéros sont-ils stockés sous forme de texte? Ou [BCD] (https://en.wikipedia.org/wiki/Binary-coded_decimal) (emballé ou déballé)? Ou autre chose? – Andreas

Répondre

2

Cela dépend de la façon dont les nombres sont stockés.
Sont-ils binaires?
Sont-ils signed?
Sont-ils grands ou petits endian?

En supposant oui aux deux premiers, vous pouvez utiliser la manipulation de bits, par ex.

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

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

Mais il est probablement plus facile à utiliser ByteBuffer:

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

ByteBuffer est BIG_ENDIAN par défaut.

+0

en utilisant ByteBuffer, où je précise que les 2 premiers nombres se composent de 2 octets et le troisième sur 3? En outre, les chiffres peuvent être négatifs, est-ce important? – michael

+1

'ByteBuffer' n'a pas de méthode pour obtenir 3 octets en nombre. Il peut faire 1 ('get()'), 2 ('getShort()'), 4 ('getInt()'), ou 8 ('getLong()'), tous décodés comme des nombres binaires signés deux-complément * ("signé" signifie que la valeur peut être négative) *. Si vous avez besoin d'un nombre de 3 octets, utilisez la manipulation de bits, mais je doute que vous le fassiez (voir [mon commentaire] (https://stackoverflow.com/questions/44227220/java-jdbc-driver-postgresql-parse-numbers- encoded-as-bytea-object/44227352? noredirect = 1 # comment75465770_44227220)). – Andreas

0

Pouvez-vous essayer:

For String:

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

Pour octet []:

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

Salut, j'obtiens java.lang.NumberFormatException.forInputString – michael

+0

L'appel 'toString()' sur un 'byte []' produira quelque chose comme '[B @ 15db9742'. – Andreas

+0

C'est vrai que vous obtiendrez byte [] de db mais nous ne savons pas quel est le type de données avant de les stocker. –