2017-06-30 1 views
1

Ich habe eine Klasse, die einen InputStream als Argument zum Lesen von Daten nimmt.Überprüfen Sie, ob Java InputStream von Socket kommt

public Foo { 
    private DataInput in; 

    public Foo(InputStream ism) { 
    in = new DataInputStream(ism); 
    } 

    public byte readByte() throws IOException { 
    return in.readByte(); 
    } 
} 

Manchmal wird diese Input aus einem Sockel kommen könnte, zum Beispiel

ism = new BufferedInputStream(sock.getInputStream()); 
foo = new Foo(ism); 

Meine Frage ist, ist es möglich, innerhalb von Foo zu überprüfen, ob der Eingangsstrom von Socket kommt, das heißt, es ist ein Netzwerk I/O statt lokale I/O? Da die

socket.getInputStream 

Aufruf die abstrakte Klasse zurückgibt. Ich weiß nicht, für welche konkrete Eingabestream-Implementierung getestet werden soll.

Edit: Die Motivation ist, dass es ein Stück große Java-Software, die diese Struktur hat. Foo ist an vielen Stellen erstellt. Irgendein Ort mit Dateieingabestream während andere mit Socketeingabestream. Die Software kann schlecht arbeiten, wenn das Lesen über das Netzwerk erfolgt. Ich möchte also sehen, ob es möglich ist, die beiden Szenarien für diese Software zu unterscheiden, ohne viel Code zu verändern. Ich benutze AspectJ, um die Ablaufverfolgung zu schreiben, in der Hoffnung, dieser vorhandenen Software nicht viel Unordnung zu bereiten.

+2

Nein (zumindest nicht ohne eine hässliche Lösung auf Reflektionsbasis), da Sie es in einen BufferedInputStream verpacken. Aber Sie sollten sich nicht darum kümmern müssen: Ein InputStream ist ein InputStream ist ein InputStream. Was versuchst du zu erreichen? –

+1

Nein, Sie haben die gesamte Schnittstelle von 'Foo' geschrieben, um von Sockets unabhängig und isoliert zu sein. Wenn du willst, dass 'Foo' etwas über Sockets weiß, musst du ihm einen Socket geben. – pvg

+0

Ich muss etwas verfolgen, um zu unterscheiden, wenn Foo Netzwerk lesen statt lokalen Datei lesen. – Oxdeadbeef

Antwort

1

Das Problem ist, dass ein Input ein Filterinput sein kann, die sich um einen anderen Input und Buchse nur einen Inputstream aufgebaut ist, zurückkehrt.

Ein Ansatz, sehr Schmutz & Buggy: Finden Sie die Wurzel Input, das heißt, rekursiv/Schleife, wenn es eine Instanz von Filterinput ist, überprüfen ihre Mutterinput (geschütztes Feld in). Dann überprüfen Sie die Klasse der Wurzel, der Name enthält wahrscheinlich "Socket", wenn es aus einem Socket stammt.

AspectJ Idee (Ich habe nicht so viel Erfahrung damit): Sie sollten einen Aspekt der getInputStream Methode von Socket hinzufügen können, die den zurückgegebenen InputStream in einer Liste (oder ähnlich) für spätere Überprüfung oder irgendwie speichert markiert diesen InputStream (Hinzufügen eines Flags/Methode zu?).

0

Sie können zwei Oberklassen des Eingabestreams erstellen, bevor Sie sie an die Klasse Foo übergeben.

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 {} 

Dann auf Foo Klasse:

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