byte getting read wrong from file?

Big_Bad_E :

So, I am trying to store 3 longs to a file, but it will a lot of data so I convert them to byte arrays and save them. My current method for saving them:

try (FileOutputStream output = new FileOutputStream(path, true)) {
                    //Put the data into my format
                    byte[] data = new byte[24];
                    main.getLogger().log(Level.INFO, "Saving most sig bits");
                    System.arraycopy(ByteUtils.longToBytes(uuid.getMostSignificantBits()), 0, data, 0, 8);
                    System.arraycopy(ByteUtils.longToBytes(uuid.getLeastSignificantBits()), 0, data, 8, 8);
                    System.arraycopy(ByteUtils.longToBytes(player.getTokens()), 0, data, 16, 8);
                    //Write data in the format
                    output.write(data);
                }

longToBytes method:

private static ByteBuffer buffer = ByteBuffer.allocate(8);

public static byte[] longToBytes(long x) {
    System.out.println(x);
    buffer.putLong(0, x);
    return buffer.array();
}

The byte array gets saved to the file, but the first byte gets truncated. the print statement in longToByes prints 8 three times.

The original longs are:

-9089798603852198353, -5339652910133477779, 5992

If I print the byte array I get:

-127, -38, -116, 84, 97, -116, 78, 47, -75, -27, -67, -8, 11, -100, -2, 109, 0, 0, 0, 0, 0, 0, 23, 104 (24 bytes)

But in the file I see: ÚŒTaŒN/µå½ø(VT symbol)œþm(nul)(nul)(nul)(nul)(nul)(nul)(etb)h which is 23 bytes (the first box doesn't show in notepad++)

but if I read it using

bytes = IOUtils.toByteArray(new FileReader(file));

I see:

64, -38, -116, 84, 97, -116, 78, 47, -75, -27, -67, -8, 11, -100, -2, 109, 0, 0, 0, 0, 0, 0, 23, 104 (24 bytes)

-127 is replaced with 64 somehow.

I concat the byte with "" to print it btw.

xiaofeng.li :

Do not use FileReader to read raw bytes from file. Use FileInputStream instead.

The problem with FileReader is that it reads chars, not bytes, from the file, by trying to decode the bytes using some character encoding (the default one if none was given).

bytes = IOUtils.toByteArray(new FileInputStream(file));

Alternatively you can use DataOutputStream to write long directly to an output stream and use DataInputStream to read from an input stream.

try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
    out.writeLong(uuid.getMostSignificantBits());
    out.writeLong(uuid.getLeastSignificantBits());
    out.writeLong(player.getTokens());
}

try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
    long uuidMSB = in.readLong();
    long uuidLSB = in.readLong();
    long tokens = in.readLong();
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=68909&siteId=1