sean
sean

Reputation: 1832

Detect the type of the target (File/Socket/etc) of an OutputStream in Java

Suppose I am passed an OutputStream variable. Is there any way to detect if the source of the OutputStream is an open file, or open socket etc?

If it is not possible, is it better if I know the variable is of type FileOutputStream, and hence I can get its FileDescriptor. Thank you.


UPDATE:

Each FileOutputStream instance has a FileDescriptor. I couldn't distinguish its source because from the Java document:

Instances of the file descriptor class serve as an opaque handle to the underlying machine-specific structure representing an open file, an open socket, or another source or sink of bytes. The main practical use for a file descriptor is to create a FileInputStream or FileOutputStream to contain it.


UPDATE2:

I'm developing an automated tool, built on top of a customized JVM, to analyze Java bytecode, and determine how many bytes the program writes to a file or sends over the socket, etc (in very simple programs). File, Socket etc are then processed differently.

The customized JVM lets me know when it executes the bytecode instruction INVOKEVIRTUAL, and I can check that the callee is of OutputStream. Now what I need to do is to determine where this OutputStream writes to File/Socket etc.

Upvotes: 0

Views: 360

Answers (3)

Andreas
Andreas

Reputation: 159135

Since you're basically putting breakpoints on all calls to write, you need to examine the actual class for the method call:

  • If it's a FilterOutputStream (one of it's subclasses), ignore it. The write method of the wrapped stream will be called too.
  • If it's java.net.SocketOutputStream (not public, subclass of FileOutputStream), you know the target is a socket.
  • If it's FileOutputStream (not a subclass), the private field path has the file path used to open the stream.
  • If it's a ByteArrayOutputStream, you know the target is a memory buffer.
  • If it's something else, you'd need to research how to handle it, or just ignore.

Upvotes: 0

yelliver
yelliver

Reputation: 5926

Thinking simply, you can use instance of

if(myStream instanceof FileOutputStream){
    //this is FileOutputStream
}

But there are some situation that you cannot detect, example if that FileOutputStream is wrapped by an other OutputStream (like FilterOutputStream). So, if the instance of your stream is FilterOutputStream, you have to find the real one inner. When a stream is wrapped:

 public FilterOutputStream(OutputStream out) {
        this.out = out;
 }

But, by normal way, we cannot get this.out (protected) out to run instance of again. I think about reflection to get a protected or private field (Java reflection - access protected field)

And BUT again, if the inner stream is another FilterOutputStream again!!! you have to use a recursive function to detect.

Imagine Stream in Java like Matroska puppet!

This is just my idea. If you want to fully control it. You have to see the tree of Java IO

enter image description here

Upvotes: 3

M Sach
M Sach

Reputation: 34424

use instanceof operator what type of object it is. For eaxmple you can check

if(currentObject instanceof FileOutputStream){}

or you can use

yourObject.getClass().getName()

Upvotes: -1

Related Questions