Search code examples
javacfiletext-filesbinaryfiles

How to read data (either binary or text) in C from a file written in Java?


Writing in Java:

File file = new File("abc");
try(FileOutputStream fos = new FileOutputStream(file)) {
    FileChannel outChannel = fos.getChannel();
    ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES*3).order(ByteOrder.nativeOrder());
    buffer.putInt(154);
    buffer.putint(98);
    buffer.putInt(6);
    outChannel.write(buffer);


    IntStream.rangeClosed(1,3).forEach((iter) -> {
        String reqString = (Integer.toString(iter) + "_string");
        byte[] bytes = reqString.getBytes(Charset.forName("US-ASCII"));
        ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length).order(ByteOrder.nativeOrder());
        byteBuffer.put(bytes);
        try {
            outChannel.write(byteBuffer);
        }
        catch(IOException ex) {
            ex.printStackTrace();
        }
    });
}   
catch(IOException ex) {
    ex.printStackTrace();
}

Reading in C: int main() { int one,two,three; FILE *fp = fopen("abc","r+");

fscanf(fp,"%d",&one);
fscanf(fp,"%d",&two);
fscanf(fp,"%d",&three);

printf("%d %d %d",one,two,three);

char ch;
fread(&ch,sizeof(char),1,fp);
while(ch!= '\0') {
    printf("%c",ch);
    fread(&ch,sizeof(char),1,fp);
} 
return 0;
}

To which the output is: [output1]

I don't understand what I see. There are three value and none of which were written by me. Are they memory locations? or Garbage values?

In which format does the Java write a file. Since, C reads in native order of the underlying platform I tried to use ByteBuffer. If I use DataOutputService, I though that the Java writes in `BIG_ENDIAN' format and C might not be able to read a proper value.

Also, how do I write and read a string in this scenario. Java, by default uses UTF-8, hence, I didn't use FileOutputStream directly, instead converted they into bytes of ASCII format so that I can read them character by character. But, no output is shown. When can I use fscanf(fp,"%s",string) (string is a char datatype variable with sufficient memory allocated)*?


Ideal solution would be where Java is able to write Data in particular order and C is able to read it using fscanf(), as a result it would be easier to identify integers/floats/strings.


Solution

  • My Java is kind of rusty, but it seems what you're writing to the file is three 4-byte integers, in sequence, and in machine order of bytes (so probably little-endian). That means your file should have (in hex):

    9a 00 00 00 62 00 00 00 06 00 00 00
    

    But your scan expected to see the numbers as space-separated text, e.g. (in hex)

    31 35 34 20 39 38 20 36 0a
    

    You should probably use something like fread(), which doesn't do parsing:

    size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    

    and the target should be the address of something like an int[3].