java endian_java的little-endian和big-endian

转自

http://blogger.org.cn/blog/more.asp?name=hongrui&id=23869

java是与CPU无关的编程语言,但是java究竟是little-endian还是big-endian呢,因为java诞生于soalris

平台,最初的solaris运行于SPARC cpu上,SUN的SPARC和IBM的POWER

PC均是big-endian,所以java也是big-endian。

判断java是big endian的代码

public final static int swabInt(int v)

{

return (v

>>> 24) | (v

<< 24) |

((v <<

8) & 0x00FF0000) | ((v

>> 8) &

0x0000FF00);

}

public static void main(String argv[])

{

// before 0x01020304

// after 0x04030201

int v = 0x01020304;

System.out.println("before : 0x"

+ Integer.toString(v,16));

System.out.println("after : 0x" + Integer.toString(swabInt(v),16));

}

// take 16-bit short apart into two 8-bit bytes.

short x = 0xabcd;

byte high = (byte)(x

>>> 8);

byte low = (byte)x;

System.out.println( "x=" + x + " high=" + high + " low=" + low

);

big endian是指低地址存放最高有效字节(MSB),而little

endian则是低地址存放最低有效字节(LSB)。

Big Endian

低地址 高地址

----------------------------------------->

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| 12 | 34 | 56 | 78 |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian

低地址 高地址

----------------------------------------->

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| 78 | 56 | 34 | 12 |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

如果你做单机程序,这个基本不用考虑,如何和java程序通讯也没有问题,java中在AIX下生成的对象被序列化后能够在windows下正确的反序列化,如果不这样,EJB也就不存在了。

如果你和C++的程序通讯,问题就有了,C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而JAVA编写的程序则唯一采用big

endian方式来存储数据。

你在x86平台上,使用c语言通过socket把0x12345678发给java的serversocket,得到的是0x78563412,C程序传给JAVA程序之前有必要进行字节序的转换工作。

所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big

endian方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。

c/c++中发送方htonl,接收方ntohl。

fseek(f,0L,SEEK_END); unsigned int tcount=total;

tcount=htonl(tcount);

memcpy( &buffer[1], &tcount,

4);

Java中不用做转换。

DataOutputStream.writeInt();

DataInputStream.readInt();

c语言转换的4个宏

ntoh:network->host

hton:host->network

ntohs和htons针对2字节的数

ntohl和htonl针对4字节的数

为了保证代码的移植性,必须用这两个函数。

htons(): reorder the bytes of a 16-bit unsigned

value from processor order to network order. The macro name can be

read "host to network short."

htonl(): reorder the bytes of a 32-bit unsigned

value from processor order to network order. The macro name can be

read "host to network long."

ntohs(): reorder the bytes of a 16-bit unsigned

value from network order to processor order. The macro name can be

read"network to host short."

ntohl(): reorder the bytes of a 32-bit unsigned

value from network order to processor order. The macro name can be

read "network to host long."

#if defined(BIG_ENDIAN) &&

!defined(LITTLE_ENDIAN)

#define htons(A) (A)

#define htonl(A) (A)

#define ntohs(A) (A)

#define ntohl(A) (A)

#elif defined(LITTLE_ENDIAN) &&

!defined(BIG_ENDIAN)

#define htons(A) ((((uint16)(A) & 0xff00)

>> 8) | \

(((uint16)(A) & 0x00ff)

<< 8))

#define htonl(A) ((((uint32)(A) & 0xff000000)

>> 24) | \

(((uint32)(A) & 0x00ff0000)

>> 8) | \

(((uint32)(A) & 0x0000ff00)

<< 8) | \

(((uint32)(A) & 0x000000ff)

<< 24))

#define ntohs htons

#define ntohl htohl

#else

#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but

not both."

#endif

但是如果不是走网络,c语言把结构直接写入了文件,那末java读Little Endian 就麻烦一些,这方面的代码很多。

使用jdk1.4以后的版本,

float f = ByteBuffer.wrap( array ).order( ByteOrder.LITTLE_ENDIAN

).getFloat();

否则就得自己写代码了

package com.mindprod.ledatastream;

import java.io.DataOutput;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.OutputStream;

public class LEDataOutputStream implements DataOutput

{

// ------------------------------ FIELDS

------------------------------

byte w[];

protected DataOutputStream d;

// -------------------------- STATIC METHODS

--------------------------

public static final String getCopyright()

{

return "LeDataStream 1.7

freeware copyright (c) 1998-2007 Roedy Green, Canadian Mind

Products, http://mindprod.comroedyg@mindprod.com";

}

// --------------------------- CONSTRUCTORS

---------------------------

public LEDataOutputStream( OutputStream out

)

{

this.d = new

DataOutputStream( out );

w = new byte[8];// work

array for composing output

}

// ------------------------ INTERFACE METHODS

------------------------

// --------------------- Interface DataOutput

---------------------

public final synchronized void write( int b )

throws IOException

{

d.write( b );

}

public final void write( byte b[] ) throws

IOException

{

d.write( b, 0, b.length

);

}

public final synchronized void write( byte

b[],

int off,

int len ) throws IOException

{

d.write( b, off, len

);

}

public final void writeBoolean( boolean v )

throws IOException

{

d.writeBoolean( v

);

}

// p u r e l y w r a p p e r m e t h o d

s

// We cannot inherit since DataOutputStream is

final.

public final void writeByte( int v ) throws

IOException

{

d.writeByte( v );

}

public final void writeShort( int v ) throws

IOException

{

w[ 0 ] = (byte) v;

w[ 1 ] = (byte) ( v

>> 8 );

d.write( w, 0, 2

);

}

public final void writeChar( int v ) throws

IOException

{

// same code as

writeShort

w[ 0 ] = (byte) v;

w[ 1 ] = (byte) ( v

>> 8 );

d.write( w, 0, 2

);

}

public final void writeInt( int v ) throws

IOException

{

w[ 0 ] = (byte) v;

w[ 1 ] = (byte) ( v

>> 8 );

w[ 2 ] = (byte) ( v

>> 16 );

w[ 3 ] = (byte) ( v

>> 24 );

d.write( w, 0, 4

);

}

public final void writeLong( long v ) throws

IOException

{

w[ 0 ] = (byte) v;

w[ 1 ] = (byte) ( v

>> 8 );

w[ 2 ] = (byte) ( v

>> 16 );

w[ 3 ] = (byte) ( v

>> 24 );

w[ 4 ] = (byte) ( v

>> 32 );

w[ 5 ] = (byte) ( v

>> 40 );

w[ 6 ] = (byte) ( v

>> 48 );

w[ 7 ] = (byte) ( v

>> 56 );

d.write( w, 0, 8

);

}

public final void writeFloat( float v ) throws

IOException

{

writeInt(

Float.floatToIntBits( v ) );

}

public final void writeDouble( double v ) throws

IOException

{

writeLong(

Double.doubleToLongBits( v ) );

}

public final void writeBytes( String s ) throws

IOException

{

d.writeBytes( s );

}

public final void writeChars( String s ) throws

IOException

{

int len =

s.length();

for ( int i = 0; i

< len; i++ )

{

writeChar( s.charAt( i ) );

}

}// end

writeChars

public final void writeUTF( String str ) throws

IOException

{

d.writeUTF( str );

}

// -------------------------- OTHER METHODS

--------------------------

// L I T T L E E N D I A N W R I T E R

S

// Little endian methods for multi-byte numeric

types.

// Big-endian do fine for single-byte types and

strings.

public final void close() throws

IOException

{

d.close();

}

// DataOutputStream

public void flush() throws IOException

{

d.flush();

}

public final int size()

{

return d.size();

}

}// end LEDataOutputStream

package com.mindprod.ledatastream;

import java.io.DataInput;

import java.io.DataInputStream;

import java.io.IOException;

import java.io.InputStream;

public class LEDataInputStream implements DataInput

{

// ------------------------------ FIELDS

------------------------------

byte w[];

protected DataInputStream d;

protected InputStream in;

// -------------------------- STATIC METHODS

--------------------------

public static final String getCopyright()

{

return "LeDataStream 1.7

freeware copyright (c) 1998-2007 Roedy Green, Canadian Mind

Products, http://mindprod.comroedyg@mindprod.com";

}

public final static String readUTF( DataInput in

) throws IOException

{

return

DataInputStream.readUTF( in );

}

// --------------------------- CONSTRUCTORS

---------------------------

// i n s t a n c e v a r i a b l e s

public LEDataInputStream( InputStream in )

{

this.in = in;

this.d = new

DataInputStream( in );

w = new byte[8];

}

// ------------------------ INTERFACE METHODS

------------------------

// --------------------- Interface DataInput

---------------------

public final void readFully( byte b[] ) throws

IOException

{

d.readFully( b, 0,

b.length );

}

public final void readFully( byte b[], int off,

int len ) throws IOException

{

d.readFully( b, off, len

);

}

public final int skipBytes( int n ) throws

IOException

{

return d.skipBytes( n

);

}

public final boolean readBoolean() throws

IOException

{

return

d.readBoolean();

}

public final byte readByte() throws

IOException

{

return

d.readByte();

}

public final int readUnsignedByte() throws

IOException

{

return

d.readUnsignedByte();

}

// L I T T L E E N D I A N R E A D E R

S

// Little endian methods for multi-byte numeric

types.

// Big-endian do fine for single-byte types and

strings.

public final short readShort() throws

IOException

{

d.readFully( w, 0, 2

);

return (short) ( ( w[ 1

] & 0xff ) << 8 | (

w[ 0 ] & 0xff ) );

}

public final int readUnsignedShort() throws

IOException

{

d.readFully( w, 0, 2

);

return ( ( w[ 1 ]

& 0xff ) << 8 | ( w[

0 ] & 0xff ) );

}

public final char readChar() throws

IOException

{

d.readFully( w, 0, 2

);

return (char) ( ( w[ 1 ]

& 0xff ) << 8 | ( w[

0 ] & 0xff ) );

}

public final int readInt() throws

IOException

{

d.readFully( w, 0, 4

);

return ( w[ 3 ] )

<< 24

| ( w[ 2 ] & 0xff )

<< 16

| ( w[ 1 ] & 0xff )

<< 8

| ( w[ 0 ] & 0xff );

}

public final long readLong() throws

IOException

{

d.readFully( w, 0, 8

);

return (long) ( w[ 7 ] )

<< 56

|

(long) ( w[ 6 ] & 0xff )

<< 48

| (long) ( w[ 5 ] & 0xff )

<< 40

| (long) ( w[ 4 ] & 0xff )

<< 32

| (long) ( w[ 3 ] & 0xff )

<< 24

| (long) ( w[ 2 ] & 0xff )

<< 16

| (long) ( w[ 1 ] & 0xff )

<< 8

| (long) ( w[ 0 ] & 0xff );

}

public final float readFloat() throws

IOException

{

return

Float.intBitsToFloat( readInt() );

}

public final double readDouble() throws

IOException

{

return

Double.longBitsToDouble( readLong() );

}

public final String readLine() throws

IOException

{

return

d.readLine();

}

public final String readUTF() throws

IOException

{

return

d.readUTF();

}

// -------------------------- OTHER METHODS

--------------------------

public final void close() throws

IOException

{

d.close();

}

// InputStream

// p u r e l y w r a p p e r m e t h o d

s

// We can't simply inherit since dataInputStream

is final.

public final int read( byte b[], int off, int

len ) throws IOException

{

// For efficiency, we

avoid one layer of wrapper

return in.read( b, off,

len );

}

}// end class LEDataInputStream

java io的代码

package com.macfaq.io;

import java.io.*;

public class LittleEndianOutputStreamextends FilterOutputStream

{

protected int written;

public LittleEndianOutputStream(OutputStream out)

{

super(out);

}

public synchronized void write(int b) throws IOException

{

out.write(b);

written++;

}

public synchronized void write(byte[] data, int offset, int

length)

throws IOException {

out.write(data, offset, length);

written += length;

}

public void writeBoolean(boolean b) throws IOException

{

if (b) this.write(1);

else this.write(0);

}

public void writeByte(int b) throws IOException

{

out.write(b);

written++;

}

public void writeShort(int s) throws IOException

{

out.write(s & 0xFF);

out.write((s

>>> 8)

& 0xFF);

written += 2;

}

public void writeChar(int c) throws IOException

{

out.write(c & 0xFF);

out.write((c

>>> 8)

& 0xFF);

written += 2;

}

public void writeInt(int i) throws IOException

{

out.write(i & 0xFF);

out.write((i

>>> 8)

& 0xFF);

out.write((i

>>> 16)

& 0xFF);

out.write((i

>>> 24)

& 0xFF);

written += 4;

}

public void writeLong(long l) throws IOException

{

out.write((int) l &

0xFF);

out.write((int) (l

>>> 8)

& 0xFF);

out.write((int) (l

>>> 16)

& 0xFF);

out.write((int) (l

>>> 24)

& 0xFF);

out.write((int) (l

>>> 32)

& 0xFF);

out.write((int) (l

>>> 40)

& 0xFF);

out.write((int) (l

>>> 48)

& 0xFF);

out.write((int) (l

>>> 56)

& 0xFF);

written += 8;

}

public final void writeFloat(float f) throws IOException

{

this.writeInt(Float.floatToIntBits(f));

}

public final void writeDouble(double d) throws IOException

{

this.writeLong(Double.doubleToLongBits(d));

}

public void writeBytes(String s) throws IOException

{

int length = s.length();

for (int i = 0; i < length; i++)

{

out.write((byte) s.charAt(i));

}

written += length;

}

public void writeChars(String s) throws IOException

{

int length = s.length();

for (int i = 0; i < length; i++)

{

int c = s.charAt(i);

out.write(c &

0xFF);

out.write((c

>>> 8)

& 0xFF);

}

written += length * 2;

}

public void writeUTF(String s) throws IOException

{

int numchars = s.length();

int numbytes = 0;

for (int i = 0 ; i < numchars

; i++) {

int c = s.charAt(i);

if ((c >= 0x0001)

&& (c <= 0x007F))

numbytes++;

else if (c > 0x07FF)

numbytes += 3;

else numbytes += 2;

}

if (numbytes > 65535) throw

new UTFDataFormatException();

out.write((numbytes

>>> 8)

& 0xFF);

out.write(numbytes &

0xFF);

for (int i = 0 ; i < numchars ;

i++) {

int c = s.charAt(i);

if ((c >= 0x0001)

&& (c <= 0x007F))

{

out.write(c);

}

else if (c > 0x07FF)

{

out.write(0xE0 | ((c

>> 12) &

0x0F));

out.write(0x80 | ((c

>> 6) &

0x3F));

out.write(0x80 | (c

& 0x3F));

written += 2;

}

else {

out.write(0xC0 | ((c

>> 6) &

0x1F));

out.write(0x80 | (c

& 0x3F));

written += 1;

}

}

written += numchars + 2;

}

/**

* Returns the number of bytes written to this little

endian output stream.

* (This class is not thread-safe with respect to this

method. It is

* possible that this number is temporarily less than

the actual

* number of bytes written.)

&

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值