我有一个类,它将InputStream作为参数来读取数据。
public Foo {
private DataInput in;
public Foo(InputStream ism) {
in = new DataInputStream(ism);
}
public byte readByte() throws IOException {
return in.readByte();
}
}
有时这个InputStream可能来自Socket,例如,
ism = new BufferedInputStream(sock.getInputStream());
foo = new Foo(ism);
我的问题是,是否可以从Foo内检查输入流是否来自Socket,即它是网络I / O而不是本地I / O?
socket.getInputStream
调用返回抽象类。我不知道要测试哪个具体的输入流实现。
编辑:动机是有一块具有这种结构的大型Java软件。在许多地方创建了Foo
。有些地方有文件输入流,有些地方有套接字输入流。当读取通过网络时,软件可能表现不佳。所以我想看看它是否可以进行跟踪来区分这个软件的两个场景,而不会改变它的大部分代码。我使用AspectJ来编写跟踪,希望不会给这个现有软件带来太多麻烦。
答案 0 :(得分:1)
问题是InputStream可以是围绕另一个InputStream构造的FilterInputStream,并且该套接字只返回一个InputStream。
一种方法,非常污垢& buggy :找到根InputStream,即,如果它是FilterInputStream的实例,则递归/循环,检查其父InputStream(受保护字段in
)。然后检查root的类,如果它来自Socket,名称可能包含“Socket”。
AspectJ的想法(我没有那么多的经验):你应该能够在Socket的getInputStream
方法中添加一个方面,将方法将返回的InputStream存储在一个列表(或类似的)中,以便以后检查,或以某种方式标记InputStream(向它添加标志/方法?)。
答案 1 :(得分:0)
您可以在将输入流传递到Foo
类之前创建2个超类。
NetworkInputStream nis = new NetworkInputStream(sock.getInputStream());
Foo networkFoo = new Foo(nis);
FileInputStream fis = new FileInputStream(file.getInputStream());
Foo fileFoo = new Foo(fis);
public class NetworkInputStream extends BufferedInputStream {}
public class FileInputStream extends BufferedInputStream {}
然后,在Foo课上:
public Foo(InputStream ism) {
if (ism instanceof NetworkInputStream) {
//Do whatever if it's from network stream
}
if (ism instanceof FileInputStream) {
//Do whateverelse
}
in = new DataInputStream(ism);
}