Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: Zaelsius en 12 de Julio de 2007, 04:08:18 PM

Título: Escribir little endian en J2SE
Publicado por: Zaelsius en 12 de Julio de 2007, 04:08:18 PM
Estoy programando una aplicación en J2SE 6.0, que exporta una colección de datos a un fichero binario. Estos datos contienen cadenas de texto, números enteros y números en coma flotante.

El problema es que este fichero binario será mas tarde leído por una aplicación C++ en una arquitectura little-endian, y Java trabaja internamente con la ordenación big-endian..

Llevo un rato informándome sobre el tema en Internet, pero aun no tengo claro cual es la manera "buena" de hacerlo. He visto algunos se han programado sus propias clases para esto, tipo EndianCorrectOutputStream o LEOutputStream. En otros sitios recomiendan usar ByteBuffer y su método order()..

Aunque voy a seguir buscando, si alguien tiene el code snippet definitivo por ahí, que lo pegue. La idea es usar la biblioteca de clases Java, y no tener que ponerme a convertir 'a mano'..


PD: Ah, como dije arriba, uso J2SE 6.0 y me da igual la retrocompatibilidad con JVMs antiguas..
Título: Escribir little endian en J2SE
Publicado por: ethernet en 12 de Julio de 2007, 04:22:06 PM
es más fácil darlo la vuelta en C++ que en java :P
Título: Escribir little endian en J2SE
Publicado por: Zaelsius en 12 de Julio de 2007, 04:34:49 PM
Ya, pero es que el archivo de datos resultante tendrá un tamaño considerable, y la aplicación C++ es un juego para Nintendo DS. Veo un poco absurdo tener que convertir el orden de los bytes cada vez que arranca el juego, cuando se podría hacer una sóla vez offline.

Al final me tocará ensuciarme las manos y repasarme el IEEE 754.. :evil:
Título: Escribir little endian en J2SE
Publicado por: ethernet en 12 de Julio de 2007, 07:16:06 PM
Yo no veo el problema de hacerlo en java igual que lo harías en C++, con operaciones  a nivel de bits haciendo swaping de los bytes.

Lo único que hay que tner en cuenta es la bazofia que es java von los signed y unsgineds.

Otra cosa que podrías hacer es usar DataOutputStream pasandole un stream que escribiese los bytes al revés. Unreal lo hace así y tú no eres menos que tim sweney :P
Título: Escribir little endian en J2SE
Publicado por: ethernet en 12 de Julio de 2007, 08:13:43 PM

FArchive& ByteOrderSerialize( void* V, INT Length )
{
#if __INTEL_BYTE_ORDER__
Serialize( V, Length );
#else
if( ArIsPersistent )
{
// Transferring between memory and file, so flip the byte order.
for( INT i=Length-1; i>=0; i-- )
Serialize( (BYTE*)V + i, 1 );
}
else
{
// Transferring around within memory, so keep the byte order.
Serialize( V, Length );
}
#endif
return *this;
}


del código del unreal, fichero UnArc.h dentro de Core
Título: Escribir little endian en J2SE
Publicado por: Zaelsius en 12 de Julio de 2007, 09:14:40 PM
Gracias por las molestias ethy :-*

Al final voy a usar una clase third-party, LEDataOutputStream (http://mindprod.com/products1.html#LEDATASTREAM), que es una versión de DataOutputStream que escribe en little-endian. Código de ejemplo sacado de su documentación:

import java.io.*;
import com.mindprod.ledatastream.*;

// O P E N
FileOutputStream fos = new FileOutputStream( "C:/temp/temp.out", false /* append */ );
// NOTE: LEDataOutputStream is available free from Canadian Mind Products.
// See http://mindprod.com/products.html#ledatastream.
LEDataOutputStream ledos = new LEDataOutputStream( fos );

// W R I T E
ledos.writeBoolean( true );
ledos.writeByte( (byte)44 );
ledos.writeBytes( "kangaroo" /* string -> LSB 8-bit */ );
ledos.writeChar( 'a' );
ledos.writeChars( "dingo" /* string 16-bit Unicode */ );
ledos.writeDouble( 3.14D );
ledos.writeFloat( 3.14F );
ledos.writeInt( 149 );
ledos.writeLong( 149L );
ledos.writeShort( (short)149 );


ledos.flush();

// C L O S E
ledos.close();


Así me ahorro codificar mis propias rutinas para cambiar el orden de bytes(ints, floats..) y me queda un código más compacto.