3

I have a strange problem with java. I want to write (amongst others) a byte[] in an ObjectOutputStream and from there to a new file. That byte-array represent an other file read from disk.

Later, after writing into the newly created file, I want to read from that file. But the byte[] which is now read from the ObjectInputStream is different from the written one.

And that is my question: WHY the heck is that byte[] different?

To make it clear and for every one to check, I wrote a short program, which will exactly show what I mean:

import java.io.*;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.security.MessageDigest;
import org.bouncycastle.util.encoders.Hex;

public class MyTest {

    public static void main(String[] args) throws Exception {

        // 1st step:
        // ------------------------------------------------
        byte[] data = openFile();

        // Create file to write
        FileOutputStream fos = new FileOutputStream(new File("test"));
        ObjectOutputStream oosf = new ObjectOutputStream(fos);
        // Write byte[]-length and byte[]
        oosf.writeInt(data.length);
        oosf.write(data);

        // Flush & Close
        fos.flush();
        fos.close();

        // Print hash value of saved byte[]
        try {
            final MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
            messageDigest.reset();
            System.out.println(new String(Hex.encode(messageDigest.digest(data))));
        } catch (Exception e) {
        }

        // 2nd step
        // ------------------------------------------------

        // Open just saved file
        FileInputStream fis = new FileInputStream(new File("test"));
        ObjectInputStream ois = new ObjectInputStream(fis);

        // Read the length and create a byte[]
        int length = ois.readInt();
        byte[] dataRead = new byte[length];
        // Read the byte[] itself
        ois.read(dataRead);

        // Print hash value of read byte[]
        try {
            final MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
            messageDigest.reset();
            System.out.println(new String(Hex.encode(messageDigest.digest(dataRead))));
        } catch (Exception e) {
        }

        // Both printed hash values should be the same

    }

    private static byte[] openFile() throws Exception {
        // Download a sample file which will be converted to a byte[]
        URL website = new URL("http://www.marcel-carle.de/assets/Cryptonify/Cryptonify-1.7.8.zip");
        ReadableByteChannel rbc = Channels.newChannel(website.openStream());
        FileOutputStream fos2 = new FileOutputStream("tmp");
        fos2.getChannel().transferFrom(rbc, 0, 1 << 24);
        fos2.flush();
        fos2.close();

        // Open downloaded file and convert to byte[]
        File selectedFile = new File("tmp");
        FileInputStream fis1 = new FileInputStream(selectedFile);
        byte[] data = new byte[(int) selectedFile.length()];
        fis1.read(data);
        fis1.close();


        return data;
    }
}

I hope you can help me!

Nick
  • 4,302
  • 2
  • 24
  • 38
Ph3n1x
  • 307
  • 7
  • 13
  • they differ in nearly all bytes from one index on... I did not checked further and now generating a hash value and they differ – Ph3n1x Oct 26 '12 at 21:58
  • 2
    Try flushing and closing the outermost stream (i.e. the ObjectOutputStream) and not the FileOutputStream. Then stop ignoring exceptions. Then stop ignoring the return value of InputStream.read() and read in a loop until the method returns -1. That said, why use Object streams if you don't write and read objects? – JB Nizet Oct 26 '12 at 22:00
  • You should check, perhaps you'll notice an offset of some sort. – zmbq Oct 26 '12 at 22:00
  • Ahhhh, thanks JB Nizet! I flushed and closed the wrong Stream... Thanks a lot! – Ph3n1x Oct 26 '12 at 22:12

1 Answers1

5

You're ignoring exceptions; you aren't closing the right stream; and you're assuming that read() fills the buffer. Use readFully(). You aren't writing objects so you may as well use DataInputStream and DataOutputStream for this and save a little space.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • This code snippet is a short written example, but I found the error, I closed the wrong stream. In my real program, I am using readFully(), just forgotten to copy it to my sample project. – Ph3n1x Oct 26 '12 at 22:14
  • Thank you. Could not figure out a similar problem. Changed read() to readFully() and now all is well!! – Paul - Soura Tech LLC Apr 27 '16 at 19:31