Native Code :
writing number 27 using fwrite().
int main()
{
int a = 27;
FILE *fp;
fp = fopen("/data/tmp.log", "w");
if (!fp)
return -errno;
fwrite(&a, 4, 1, fp);
fclose();
return 0;
}
Reading back the data(27) using DataInputStream.readInt() :
public int readIntDataInputStream(void)
{
String filePath = "/data/tmp.log";
InputStream is = null;
DataInputStream dis = null;
int k;
is = new FileInputStream(filePath);
dis = new DataInputStream(is);
k = dis.readInt();
Log.i(TAG, "Size : " + k);
return 0;
}
O/p
Size : 452984832
Well that in hex is 0x1b000000
0x1b
is 27
. But the readInt() is reading the data as big endian while my native coding is writing as little endian. . So, instead of 0x0000001b
i get 0x1b000000
.
Is my understanding correct? Did anyone came across this problem before?
From the Javadoc for readInt()
:
This method is suitable for reading bytes written by the
writeInt
method of interfaceDataOutput
If you want to read something written by a C program you'll have to do the byte swapping yourself, using the facilities in java.nio
. I've never done this but I believe you would read the data into a ByteBuffer
, set the buffer's order to ByteOrder.LITTLE_ENDIAN
and then create an IntBuffer
view over the ByteBuffer
if you have an array of values, or just use ByteBuffer#getInt()
for a single value.
All that aside, I agree with @EJP that the external format for the data should be big-endian for greatest compatibility.
There are multiple issues in your code:
You assume that the size of int
is 4
, it is not necessarily true, and since you want to deal with 32-bit ints, you should use int32_t
or uint32_t
.
You must open the file in binary more to write binary data reliably. The above code would fail on Windows for less trivial output. Use fopen("/data/tmp.log", "wb")
.
You must deal with endianness. You are using the file to exchange data between different platforms that may have different native endianness and/or endian specific APIs. Java seems to use big-endian, aka network byte order, so you should convert the values on the C platform with the hton32()
utility function. It is unlikely to have significant impact on performance on the PC side, as this function is usually expanded inline, possibly as a single instruction and most of the time will be spent waiting for I/O anyway.
Here is a modified version of the code:
#include <endian.h>
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint32_t a = hton32(27);
FILE *fp = fopen("/data/tmp.log", "wb");
if (!fp) {
return errno;
}
fwrite(&a, sizeof a, 1, fp);
fclose();
return 0;
}
User contributions licensed under CC BY-SA 3.0