检查Java InputStream是否来自Socket

时间:2017-06-30 06:21:34

标签: java sockets abstract-class

我有一个类,它将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来编写跟踪,希望不会给这个现有软件带来太多麻烦。

2 个答案:

答案 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);
}