-1

my purpose to read from stream as byte per digit do some logic and write back to binary file

Lets say the representation of data is 0F000200 17000000 07003B00

so we have method to represent it

   InputStream stream = new FileInputStream(args[0]);

    private static int readShort(InputStream stream) throws IOException {
       return stream.read() + stream.read() * 10;
    }

    // ***** when we read the results ******

    int day = readShort(stream); // => 15
    int month = readShort(stream); //  => 2
    int year_suffix = readShort(stream); // => 23
    int hour = readShort(stream); //  => 0
    int minute = readShort(stream); //  => 7
    int second = readShort(stream); // => 59

Now I want to write it back as byte array so I did:

   FileOutputStream stream = new FileOutputStream("/path/to/file");

    writeShort(stream, day);
    writeShort(stream, month);
    writeShort(stream, year);
    writeShort(stream, hour);
    writeShort(stream, minute);
    writeShort(stream, second);


 private static void writeShort(OutputStream stream, int value) throws IOException {
      stream.write(value % 10);
      stream.write(value / 10);
 }

But when I look into output file I see the header is not the same

the value are 05010200 03020000 07000905 instead of 0F000200 17000000 07003B00

please suggest ( picture from Hex fiend editor)

enter image description here

VitalyT
  • 1,671
  • 3
  • 21
  • 49
  • 3
    "representation of data is 0F000200 17000000 07003B00" -- this is not BCD. Is the example wrong, or the description? `readShort` only accidentally handled this data correctly (because every second byte is zero) – harold Jul 08 '23 at 11:43
  • Ok , edited the question. Lets ignore the method names, and assume second byte wont be zero, it will be unsigned – VitalyT Jul 08 '23 at 11:50
  • It seems you're only interested in the high byte (and your interpretation is as if it's a *low* byte), so why don't you just read that instead of reading a short? – g00se Jul 08 '23 at 12:03
  • It could be that every byte will represent a digit, now the low byte it is accidentally zero. Even though need to gave same results after write – VitalyT Jul 08 '23 at 12:23
  • So, let's take the first datum. What would it mean for 'day' were the second byte not zero? – g00se Jul 08 '23 at 12:24
  • If each byte is meant to represent a decimal digit, there shouldn’t be any bytes with values greater than 0x09 right? – Tim Moore Jul 08 '23 at 12:38
  • @Tim Moore - the max value of each byte can be 255 (as decimal value) – VitalyT Jul 08 '23 at 12:50
  • @g00se I guess the day will be bigger – VitalyT Jul 08 '23 at 12:51
  • 1
    If the format was BCD (unpacked version, one digit per byte), then 15 really would be stored as 0501, which you `writeShort` produces. But apparently that is not how the format works, so how *is* it meant to work? If each byte can be max 255, isn't it just a normal short that's stored there, not in any fancy format? – harold Jul 08 '23 at 12:51
  • *@g00se I guess the day will be bigger* Is that meant to be a joke? How can it be bigger than 0XFF or decimal 31 for that matter? – g00se Jul 08 '23 at 12:53
  • The data is 3rd party and hard to say right now (will check it tomorrow) , but as I know every 1 byte should represent unsigned number with format ( day, month, year ..) , my question was if I read number this way (stream.read() + stream.read() * 10), how i should write to output in order to have same result (reverse) in editor – VitalyT Jul 08 '23 at 13:06
  • `stream.write(value % 256); stream.write(value / 256);` would reproduce the data that you've shown so far, but that is certainly not BCD, and is not symmetric with `stream.read() + stream.read() * 10` (which does not make sense anyway, given the data that you've shown so far) – harold Jul 08 '23 at 13:22
  • Did it, didnt work – VitalyT Jul 08 '23 at 13:35

1 Answers1

0

If you really want to read and write short values spread over two bytes, little-endian (i.e., least significant byte first), you can modify your code like this (but there probably is a more efficient way):

private static int readShort(InputStream stream) throws IOException {
    return stream.read() + stream.read() * 256;
}

private static void writeShort(OutputStream stream, int value) throws IOException {
    stream.write(value % 256); // or value & 0xFF
    stream.write(value / 256); // or value >> 8
}

The point is, you don't want to read and write a decimal digit (10 possible values) at a time, but a byte (256 possible values) at a time.

Walter Tross
  • 12,237
  • 2
  • 40
  • 64