从PHP中的Java DataOutputStream读取二进制数据时的整数格式是什么?

从PHP中的Java DataOutputStream读取二进制数据时的整数格式是什么?

问题描述:

I'm aware that this is probably not the best idea but I've been playing around trying to read a file in PHP that was encoded using Java's DataOutputStream.

Specifically, in Java I use:

dataOutputStream.writeInt(number);

Then in PHP I read the file using:

$data = fread($handle, 4);
$number = unpack('N', $data);

The strange thing is that the only format character in PHP that gives the correct value is 'N', which is supposed to represent "unsigned long (always 32 bit, big endian byte order)". I thought that int in java was always signed?

Is it possible to reliably read data encoded in Java in this way or not? In this case the integer will only ever need to be positive. It may also need to be quite large so writeShort() is not possible. Otherwise of course I could use XML or JSON or something.

我知道这可能不是最好的主意,但我一直在玩试图读取文件 在使用Java的DataOutputStream编码的PHP中。 p>

具体来说,在Java中我使用: p>

  dataOutputStream.writeInt(number); 
   code>  pre> 
 
 

然后在PHP中我使用以下方法读取文件: p>

  $ data = fread($ handle,4); \  n $ number = unpack('N',$ data); 
  code>  pre> 
 
 

奇怪的是PHP中唯一给出正确值的格式字符是'N ',它应该代表“无符号长(总是32位,大端字节顺序)”。 我认为java中的 int code>总是被签名? p>

是否有可能以这种方式可靠地读取用Java编码的数据? 在这种情况下,整数只需要是正数。 它可能还需要非常大,因此 writeShort() code>是不可能的。 当然,我可以使用XML或JSON等。 p> div>

This is fine, as long as you don't need that extra bit. l (instead of N) would work on a big endian machine.

Note, however, that the maximum number that you can store is 2,147,483,647 unless you want to do some math on the Java side to get the proper negative integer to represent the desired unsigned integer.

Note that a signed Java integer uses the two's complement method to represent a negative number, so it's not as easy as flipping a bit.

DataOutputStream.writeInt:

Writes an int to the underlying output stream as four bytes, high byte first.

The formats available for the unpack function for signed integers all use machine dependent byte order. My guess is that your machine uses a different byte order than Java. If that is true, the DataOutputStream + unpack combination will not work for any signed primitive.