2

我有一个服务器端应用程序,我正试图通过 RMI 共享对它的访问权限。该应用程序具有“项目”的抽象表示,该“项目”通常表示文件,但可以表示几乎任何任意数据,包括流(流式无线电,来自传感器的流式数据)。因此,任何“项目”都可以通过 InputStream 访问(以及一个指示文件大小的方法,如果它可以知道的话)。

虽然 RMI 对于应用程序的其余部分来说已经足够了,但它确实不能处理 InputStreams。

令我震惊的是,在使用 RMI 时需要访问 InputStreams 一定是一个常见问题。所以我想知道:推荐的解决方案是什么?

请注意,我需要客户端发送和接收输入流,并且序列化为字节数组是不可行的,因为它们中的一些实际上确实表示数据流,而不仅仅是文件。

4

3 回答 3

4

我使用RMIIO库通过 RMI 共享流。

见类:com.healthmarketscience.rmiio.RemoteInputStreamcom.healthmarketscience.rmiio.RemoteOutputStream

另请参阅:使用 RMIIO 进行远程流式传输参考

于 2012-08-20T12:55:54.213 回答
0

除了传递流,你能传递一种“流句柄”吗?也就是说,一个对象本身不是流,但可以按需生成流。就像是:

public interface StreamHandle extends Serializable {
    public InputStream getStream();
}

public class WebStreamHandle implements StreamHandle {
    private URL url;
    public InputStream getStream() {
        return url.openStream();
    }
}

public class SocketStreamHandle implements StreamHandle {
    private String host;
    private int port;
    public InputStream getStream() {
        return new Socket(host, port).getInputStream();
    }
}

public class BufferStreamHandle implements StreamHandle {
    private byte[] buffer;
    public InputStream getStream() {
        return new ByteArrayInputStream(buffer);
    }
}

关键是确保代码能够独立于执行它的机器生成流。因此,您不能引用文件(除非它是您知道将在每台机器上的文件,或者是 UNC 路径),但您可以引用网络上的资源。

然后,您可以传递句柄,并按需生成流。

于 2012-08-20T13:39:38.253 回答
0

我刚刚将一个轻量级解决方案Serializable InputStream推送到 Github,用于传递一个在概念上与RMIIOInputStream非常相似的RMI 。这可能会解决您的问题。使用该库,您可以轻松地包装它以使其可序列化:InputStream

serializableStream = new SerializableInputStream(originalInputStream);

基本上,它利用在实现的类ObjectOutputStream上调用特殊方法(如果存在)的行为Serializable

private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

使用这些方法,SerializableInputStream从委托读取的转发块到RMI 框架使用InputStream的处理中。ObjectOutputStream然后这些块在另一端被反序列化(进入内存缓存或临时文件 - 这是可配置的,取决于您的需要)。

至于你的要求...

“其中一些实际上确实代表了一个数据流,而不仅仅是一个文件”

...我相信,要么您需要进一步阐明您的需求,要么重新考虑 RMI 是否真的是适合您的用例的技术:我看不出如何通过基于方法调用的接口发送(可能永无止境的)数据流可以为你解决。

于 2013-08-24T21:11:48.163 回答