7 votes

Meilleure façon d'envoyer des nombres à virgule flottante de .NET à Java et vice-versa

J'écris une application .NET qui fera un appel RPC à une application Java (via une file d'attente de messages). Les données envoyées dans les deux directions seront de grands tableaux de nombres à virgule flottante. Quelle est la meilleure façon de les sérialiser pour les envoyer sur le câble ? J'aimerais quelque chose de plus compact qu'un texte, mais indépendant de l'architecture car le serveur n'est pas forcément une machine x86. L'application Java peut être modifiée si nécessaire.

6voto

Kevin Brock Points 4695

Les primitives numériques Java sont en fait stockées (dans la JVM) et écrites (par l'intermédiaire de jnava.io.DataOutputStream y java.nio.ByteBuffer ) dans l'ordre du réseau et les valeurs à virgule flottante sont conformes à la norme IEEE. Ils sont directement interchangeables avec C#/.NET. Enfin, si .NET fournissait l'ordre des octets du réseau pour lire les doubles (voir le code ci-dessous).

Vous pouvez donc envoyer et recevoir n'importe quelle primitive en utilisant les deux classes mentionnées ici (et leurs homologues d'entrée) tant que le côté .NET lit/écrit dans l'ordre des octets du réseau, comme vous devriez toujours le faire.

Côté Java par exemple :

// Assume the following somewhere in your class
Socket socket;
DataOutputStream out = new DataOutputStream(socket.getOutputStream());

// Send a double
out.writeDouble(doubleValue);

C# pour récupérer la valeur :

Stream stream = new NetworkStream(socket, FileAccess.ReadWrite, true);
BinaryReader reader = new BinaryReader(stream, Encoding.UTF8);   

// Read double from the stream
long v = IPAddress.NetworkToHostOrder(reader.ReadInt64());   
double doubleValue = BitConverter.Int64BitsToDouble(v);

Pour l'écriture, vous faites l'inverse, C# doit écrire dans l'ordre des octets du réseau.

Stream stream = new NetworkStream(socket, FileAccess.ReadWrite, true);
BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8);

// Write double to the stream
long v = BitConverter.DoubleToInt64Bits(doubleValue);
writer.Write(IPAddress.HostToNetworkOrder(v));

Puis, du côté de Java, pour les relire :

// Some where in your class
Socket socket;
DataInputStream in = new DataInputStream(socket.getInputStream());

// To read the double
double doubleValue = in.readDouble();

Le programme C# IPAddress fournit des méthodes de lecture/écriture dans l'ordre des octets du réseau pour toutes les primitives, à l'exception de double et float, mais comme dans mon exemple, vous pouvez passer par un int 32 bits ou 64 bits respectivement.

1voto

Robert Harvey Points 103562

JSON me vient à l'esprit. Ou son équivalent binaire, BSON . Les deux ont des implémentations en Java et en .NET

1voto

EMP Points 17246

Je suis en train de lire sur Tampons de protocole et ils semblent prometteurs. Il existe une implémentation officielle de Google pour Java et une implémentation de Portage en C# par nul autre que Jon Skeet.

0voto

luke Points 6688

Le texte est vraiment le seul moyen indépendant de la plate-forme pour représenter les nombres à virgule flottante, et c'est certainement le plus facile à réaliser. Si vous êtes préoccupé par la taille de vos messages, vous pouvez toujours les compresser (GZip).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X