如何通过RMI传递InputStream

时间:2011-08-17 14:54:43

标签: java rmi inputstream fileinputstream

考虑这两个功能:

Function A将inputStream作为参数。

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

Function B加载文件内容,将其作为Function A传递给InputStream

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

如何将文件从Function B传递给Function A作为InputStream,而不是直接读取它?

我做了类似的事情:

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

这产生了以下例外:

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

修改

loadFile()正在将InputStream作为RMI响应传递。

3 个答案:

答案 0 :(得分:3)

以下应该可以正常使用

processStream(new FileInputStream(file));

您应该尝试按InputStream序列化ObjectOutputStream个实例,如

objectOutputStream.writeObject(inputStream);

你显然是在processStream()方法中做的。这就是异常试图告诉你的内容。如何正确地解决它取决于你从问题中省略的唯一功能要求。


根据评论

更新

  

我将InputStream作为RMI响应传递。

有问题。您不能将不可序列化的对象作为RMI响应传递,更不用说未读取的流。您需要以ByteArrayOutputStream通常的IO方式阅读InputStream,然后使用其toByteArray()获取byte[]并将其传递出去。类似的东西:

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.

但要小心大文件。 byte[]的每个字节都占用JVM内存的一个字节。

答案 1 :(得分:0)

你可以传递FileInputStream

processStream(new FileInputStream(yourFile));

您获得异常的原因是因为DataInputStream旨在读取原始Java类型

答案 2 :(得分:0)

该异常似乎表明您使用RMI之类的东西在远程对象上调用processStream方法?如果是这种情况,您将需要重新访问您正在做的事情。通过RMI发送数据流并不是一件容易的事。如果您保证使用小文件,您可以将文件数据复制到byte[]并将其传递给远程方法调用。但是,如果您需要处理更大的文件,那么很可能会导致客户端和/或服务器出现内存问题。在这种情况下,您应该使用rmiio之类的东西,它提供了通过RMI传输数据的实用程序。