Search code examples
javarmiinputstreamfileinputstream

How to pass an InputStream via RMI


Consider these two functions:

Function A takes inputStream as parameter.

public void processStream(InputStream stream)
{
  //Do process routine
}

Function B loads a file content to pass it to Function A as InputStream.

pulic void loadFile()
{
 File file =new File("c:\\file.txt");
 //Pass file as InputStream
}

How can I pass file from Function B to Function A as InputStream without reading it on first hand?

I did something like this:

File file = new File("c:\\file.txt");
DataInputStream stream= new DataInputStream(new FileInputStream(file));

This generated the exception below:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.io.DataInputStream

EDIT:

loadFile() is passing the InputStream as RMI response.


Solution

  • The following should work just fine

    processStream(new FileInputStream(file));
    

    You should only not attempt to serialize an InputStream instance by ObjectOutputStream like as

    objectOutputStream.writeObject(inputStream);
    

    which you're apparently doing in processStream() method. That's namely exactly what the exception is trying to tell you. How to solve it properly depends on the sole functional requirement which you omitted from the question.


    Update as per the comment

    I am passing the InputStream as an RMI response.

    There's the problem. You cannot pass non-serializable objects around as RMI response, let alone unread streams. You need to read the InputStream into a ByteArrayOutputStream the usual IO way and then use its toByteArray() to get a byte[] out of it and pass that instead. Something like:

    InputStream input = new FileInputStream(file); 
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[8192];
    
    for (int length = 0; (length = input.read(buffer)) > 0;) {
        output.write(buffer, 0, length);
    }
    
    byte[] bytes = output.toByteArray(); // Pass that instead to RMI response.
    

    Be careful with large files though. Every byte of a byte[] eats one byte of JVM's memory.