Java 如何在使用RMI时共享InputStream或OutputStream?

Java 如何在使用RMI时共享InputStream或OutputStream?,java,inputstream,rmi,outputstream,Java,Inputstream,Rmi,Outputstream,我有一个服务器端应用程序,我正试图通过RMI共享对该应用程序的访问。该应用程序具有“项”的抽象表示,该项最常用于表示文件,但可以表示几乎任何任意数据,包括流(流广播、来自传感器的流数据)。因此,任何“项”都是通过InputStream访问的(如果可以知道,还可以通过一个方法指示文件大小) 虽然RMI对于应用程序的其余部分已经足够了,但它实际上无法处理InputStreams 我突然意识到,在使用RMI时访问InputStreams必须是一个常见的问题。所以我想知道: 建议的解决方案是什么 注意:

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

虽然RMI对于应用程序的其余部分已经足够了,但它实际上无法处理InputStreams

我突然意识到,在使用RMI时访问InputStreams必须是一个常见的问题。所以我想知道: 建议的解决方案是什么

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

我使用库通过RMI共享流

参见类:
com.healthmarketscience.rmio.RemoteInputStream
com.healthmarketscience.rmio.RemoteOutputStream

另请参见:

我使用库通过RMI共享流

参见类:
com.healthmarketscience.rmio.RemoteInputStream
com.healthmarketscience.rmio.RemoteOutputStream


另请参见:

您可以传递某种“流句柄”而不是传递流吗?也就是说,对象本身不是流,但可以按需生成流。比如:

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路径),但您可以引用网络上的资源


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

您可以传递一种“流句柄”而不是传递流吗?也就是说,对象本身不是流,但可以按需生成流。比如:

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路径),但您可以引用网络上的资源


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

我刚刚向Github推出了一个轻量级解决方案,用于通过RMI传递
InputStream
,该解决方案在概念上非常类似于。这可能会解决你的问题。使用该库,您可以轻松包装
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
将从委托
InputStream
读取的块转发到RMI框架使用的处理
ObjectOutputStream
。然后,这些块在另一端被反序列化(要么进入内存缓存,要么进入临时文件——这是可配置的,取决于您的需要)

至于你方要求

其中有些实际上代表的是数据流,而不仅仅是文件


…我认为您需要进一步澄清您的需求,或者重新考虑RMI是否真的是适合您的用例的技术:我看不出如何发送(可能是永无止境的)通过基于方法调用的接口的数据流可能适合您。

我刚刚向Github推出了一个轻量级解决方案,用于通过RMI传递
InputStream
,这在概念上非常类似于。这可能会解决你的问题。使用该库,您可以轻松包装
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
将从委托
InputStream
读取的块转发到RMI框架使用的处理
ObjectOutputStream
。然后,这些块在另一端被反序列化(要么进入内存缓存,要么进入临时文件——这是可配置的,取决于您的需要)

至于你方要求

其中有些实际上代表的是数据流,而不仅仅是文件


…我认为您需要进一步澄清您的需求,或者重新考虑RMI是否真的是适合您的用例的技术:我看不出如何发送(可能是永无止境的)通过基于方法调用的接口的数据流可能适合您。

您可能感兴趣:您可能感兴趣:只要服务器连接/合并了一个web服务器以提供对URL的访问,这就可以工作。我在问题中没有说明这一点,但服务器必须始终充当代理,客户端不得自行获取数据。啊哈。我在想,在这种情况下,你的应用程序正在讨论源自远方的流(例如来自远程传感器或无线电台),在这种情况下,哪台机器检索它们并不重要。如果不是这样,那么这种方法没有多大帮助,DRCB的答案是更好的。只要服务器连接/合并了web服务器以提供对URL的访问,这种方法就会起作用。我在问题中没有说明这一点,但服务器必须始终充当代理,客户端不得自行获取数据。啊哈。我在想,在这种情况下,你的应用程序正在讨论源自远方的流(例如来自远程传感器或无线电台),在这种情况下,哪台机器检索它们并不重要。如果不是这样的话,那么这种方法没有多大帮助,DRCB的答案是更好的