J'ai une classe comme celle-ci:
//ID has short type so we need 2 bytes ID=4096; //(decimal value of 1000) //SSN has integer type so we need 4 bytes SSN=402659328; //(decimal value of 18001800) //Number has long type so we need 8 bytes Number=378492038049986131; //(decimal value of 0540AC80D6487653)
et j'ai une chaîne hexadécimale avec la valeur comme celle-ci dont chaque 2 caractères est représentatif d'un octet:
String str="1000180018000540AC80D6487653E5000100D40B7900D4C3FFF2FAFF8985";
Maintenant, je veux convertir cette chaîne en objet de classe ci-dessus dans un schéma comme celui-ci:
public class Fields implements java.io.Serializable{ public short ID; public int SSN; public long Number; }
Ce casting peut être implémenté en c ++ avec
si facilement mais comme le Y at-il un cast en Java similaire à la question C ++ est dit, je peux l'implémenter avec la sérialisation en java. Je pense que la sérialisation peut être utilisée lorsque nous sérialisons un objet de classe dans les tableaux d'octets au premier et au deuxième, nous pouvons désérialiser les octets obtenus en l'objet de classe primitif, ce qui est un peu différent de ce que je propose, car j'ai une chaîne (comme bytes) que je souhaite désérialiser. Alors, comment puis-je faire ça?
3 Réponses :
Il vous suffit de fractionner
et analyser
public Fields(String str) { ID = Short.parseShort(str.substring(0, 4), 16); SSN = Integer.parseInt(str.substring(4, 12), 16); Number = Long.parseLong(str.substring(12, 28), 16); }
La sérialisation Java a un format de données très spécifique et ne vous aide pas à analyser les données que vous obtenez avec un format prédéfini différent. Mais un Vous devez d'abord transformer votre chaîne en un tableau Que vous ayez besoin ou non de la commande ByteBuffer
a> peut être utile pour analyser ce type de données. byte []
réel. J'utiliserai une solution simple de cette réponse , n'hésitez pas à en choisir une autre plus appropriée à votre exemple: byte[] data = DatatypeConverter.parseHexBinary(str);
ByteBuffer buffer = ByteBuffer.wrap(data);
buffer.order(ByteOrder.LITTLE_ENDIAN); // maybe!
short id = buffer.getShort();
int ssn = buffer.getInt();
long number = buffer.getLong();
( )
dépend de la finalité de vos données. ByteBuffer
est défini par défaut sur BIG_ENDIAN
, vous pouvez donc simplement laisser cet appel si c'est ce dont vous avez besoin. p>
C'est une bonne utilisation de NIO ByteBuffer
.
Merci beaucoup! En changeant buffer.order (ByteOrder.LITTLE_ENDIAN);
en buffer.order (ByteOrder.BIG_ENDIAN);
le résultat que je veux a été parfaitement atteint!
@ahmadimortezaali: notez que BIG_ENDIAN est la valeur par défaut, donc dans ce cas, vous pouvez également l'omettre entièrement.
Je ne pense pas que
aurait fonctionné. La représentation octet interne de "1000"
est de 4 octets ASCII. Un pour le caractère 1
( 0x31
) suivi de 3 caractères 0
( 0x30
), et non de 0x10, 0x00
hexadécimal. Le résultat que vous obtiendrez dans id
avec
serait hexadécimal 0x31303030
et non 0x1000
.
Quoi vous devez analyser les différents composants de la chaîne.
Quelque chose comme ça devrait faire:
int id = Integer.parseInt(str.substring(0,4), 16);
Vous vouliez probablement dire int id = ...
?
Oui, j'allais le faire en 2 lignes mais j'ai changé d'avis et j'ai oublié de changer de type.
La sérialisation ne vous aidera pas. Il a un format très spécifique qui ne correspond pas au vôtre. Vous devez analyser votre chaîne manuellement.
@talex mais C ++ le font avec
facilement. Il n'y a donc aucun moyen comme
en java? Parce que la vitesse est importante pour moi et que l'analyse manuelle avec une chaîne de données à haut débit sera un goulot d'étranglement!Non
ne l'aurait pas fait facilement. Cela ne fonctionnera même pas. "1000" correspond à 4 octets ASCII, 0x31, 0x30, 0x30, 0x30, C ++ ne le convertira pas comme par magie en 2 octets 0x10, 0x00.@ahmadimortezaali si vous voulez utiliser
, vous devez utiliserc ++
:) Java n'a rien de tel.stackoverflow.com/questions/140131/...