[英]How to share an InputStream or an OutputStream while using RMI?
I have a server side application to which I'm attempting to share access to via RMI. 我有一个服务器端应用程序,试图通过RMI共享访问权限。 The application has an abstract representation of an "item" which is most commonly represents a file but could represent almost any arbitrary data including stream (streaming radio, streaming data from a sensor).
该应用程序具有“项目”的抽象表示,该项目最通常表示一个文件,但几乎可以表示任何数据,包括流(流广播,来自传感器的流数据)。 Consequently any "item" is accessed through an InputStream (alongside a method to indicate the file size if it can be known).
因此,可以通过InputStream访问任何“项目”(如果可以知道,还可以使用一种方法来指示文件大小)。
While RMI is sufficient for the rest of the application, it really can't handle InputStreams. 尽管RMI足以满足其余应用程序的需求,但它实际上无法处理InputStreams。
It strikes me that the need to access InputStreams while using RMI must be a common problem. 令我惊讶的是,在使用RMI时访问InputStreams的需求必定是一个普遍的问题。 So I was wondering: What are the recommended solutions?
所以我想知道:推荐的解决方案是什么?
Note I need the client to both send and receive input streams and serializing to a byte array is not viable because some of them actually do represent a stream of data, not just a file. 请注意,我需要客户端同时发送和接收输入流,并且序列化为字节数组是不可行的,因为其中一些实际上确实表示数据流,而不仅仅是文件。
I use RMIIO library to share streams over RMI. 我使用RMIIO库通过RMI共享流。
See classes: com.healthmarketscience.rmiio.RemoteInputStream
and com.healthmarketscience.rmiio.RemoteOutputStream
请参阅以下类:
com.healthmarketscience.rmiio.RemoteInputStream
和com.healthmarketscience.rmiio.RemoteOutputStream
See also: Remote streaming reference with RMIIO 另请参阅: RMIIO的远程流参考
Rather than passing streams, can you pass a sort of 'stream handle'? 除了传递流之外,您还可以传递一种“流句柄”吗? That is, an object which is not a stream itself, but can produce a stream on demand.
也就是说,对象本身不是流,而是可以按需生成流。 Something like:
就像是:
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);
}
}
The key thing would be to ensure that the code was able to produce a stream independently of the machine it was executed on. 关键是要确保代码能够独立于其执行的机器而产生流。 So, you couldn't refer to a file (unless it was file you knew would be on every machine, or was a UNC path), but you can refer to resources on the network.
因此,您无法引用文件(除非该文件是您知道将在每台计算机上使用的文件,或者是UNC路径),但是您可以引用网络上的资源。
Then, you could pass the handles around, and produce the streams on demand. 然后,您可以传递手柄,并按需生成流。
I just pushed a lightweight solution Serializable InputStream to Github for passing an InputStream
over RMI that is conceptually very similar to RMIIO . 我只是将轻量级解决方案Serializable InputStream推送到Github,以通过RMI传递
InputStream
,该输入流在概念上与RMIIO非常相似。 This might solve your problem. 这可能会解决您的问题。 With that library you can easily wrap your
InputStream
to make it serializable: 使用该库,您可以轻松包装
InputStream
使其可序列化:
serializableStream = new SerializableInputStream(originalInputStream);
Basically it leverages the behavior of ObjectOutputStream
to call special methods (if present) on classes that implement Serializable
: 基本上,它利用
ObjectOutputStream
的行为在实现Serializable
类上调用特殊方法 (如果存在):
private void writeObject(java.io.ObjectOutputStream out) throws IOException;
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
Using these methods, the SerializableInputStream
forwards chunks read from the delegate InputStream
into the processing ObjectOutputStream
used by the RMI framework. 使用这些方法,
SerializableInputStream
将从委托InputStream
读取的块转发到RMI框架使用的处理ObjectOutputStream
。 These chunks then get deserialized on the other end (either into an in-memory cache or into a temp file - that's configurable and depends on your needs). 然后,这些块会在另一端反序列化(进入内存缓存或临时文件中,这是可配置的,具体取决于您的需求)。
As for your requirement that... 至于你的要求...
"some of them actually do represent a stream of data, not just a file"
“其中一些确实代表数据流,而不仅仅是文件”
...I believe that either you need to further clarify your needs or reconsider if RMI is really the technique that suits your use case: I cannot see how sending (potentially never-ending) streams of data over a method-invocation-based interface could work out for you. ...我相信您要么需要进一步澄清您的需求,要么重新考虑RMI是否真的适合您的用例:我无法看到如何通过基于方法调用的接口发送(可能永无止境)数据流可以为您解决。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.