Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Escribir little endian en J2SE

Iniciado por Zaelsius, 12 de Julio de 2007, 04:08:18 PM

« anterior - próximo »

Zaelsius

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..

ethernet

es más fácil darlo la vuelta en C++ que en java :P

Zaelsius

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:

ethernet

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

ethernet


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

Zaelsius

Gracias por las molestias ethy :-*

Al final voy a usar una clase third-party, LEDataOutputStream, 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.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.