Search code examples
javaarraysserializationobjectoutputstream

How does Java's ObjectOutputStream's writeObject() method work for array?


File file = new File(path);
if (file.exists())
{
    int count;
    byte[] buffer = new byte[8192];

    BufferedInputStream fileReader = new BufferedInputStream(new FileInputStream(file));
    while ((count = fileReader.read(buffer)) >= 0)
    {
        fileOut.writeObject(buffer);
        fileOut.writeObject(count);
    }
    fileOut.writeObject("EOF");
    fileReader.close();
}

Above is the server-side codes I used to transfer files to socket originally. I first send a byte array called "buffer", then a int variable called "count" to tell client how many bytes of "buffer" array are needed to be written into file, and when file finished transferring, I send a string contained "EOF" to let client know that file transferring has done to prevent further reading on client-side. However, when I ran this program, weird things appeared, the elements of "buffer" array that server is sending did not change after first loop, which means after first loop, server kept sending the "buffer" array that contains the same elements as the one in the first loop, but I did check the values of array before fileOut.writeObject(buffer) is called by print them to the screen, and elements' values actually changed. Then this problem was solved by adding another line of code buffer = new byte[8192] after fileOut.writeObject(count), which the codes become:

File file = new File(path);
if (file.exists())
{
    int count;
    byte[] buffer = new byte[8192];

    BufferedInputStream fileReader = new BufferedInputStream(new FileInputStream(file));
    while ((count = fileReader.read(buffer)) >= 0)
    {
        fileOut.writeObject(buffer);
        fileOut.writeObject(count);
        buffer = new byte[8192];
    }
    fileOut.writeObject("EOF");
    fileReader.close();
}

Therefore I am wondering why I need to initialize "buffer" array each time before bytes of file are read into "buffer" array, but the elements of "buffer" array were changing without initializing array every time at the end of loop. Does it have something to do with the mechanics of writeObject() method of ObjectOutputStream? I am urged to know, thanks for any help!

PS: fileOut is a instance variable that is initialized by the following code:

fileOut = new ObjectOutputStream(socket.getOutputStream());

Solution

  • It's not an issue with arrays specifically. Java serialization numbers objects by ID and then only transmits each distinct object once (this prevents problems with cyclic graphs). Each time you try to send the array again, the stream just repeats the ID for the array object. On the other end, if you compare the references, you'll find they're ==. (You should also be able to tell that writing an extra 8k only increases your output size by a few bytes.)