Reputation: 1832
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.
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.
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
Reputation: 159135
Since you're basically putting breakpoints on all calls to write
, you need to examine the actual class for the method call:
FilterOutputStream
(one of it's subclasses), ignore it. The write
method of the wrapped stream will be called too.java.net.SocketOutputStream
(not public, subclass of FileOutputStream
), you know the target is a socket.FileOutputStream
(not a subclass), the private field path
has the file path used to open the stream.ByteArrayOutputStream
, you know the target is a memory buffer.Upvotes: 0
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
Upvotes: 3
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