francesc
francesc

Reputation: 343

FilterInputStream doesn't execute

I'm trying to use FilterInputStream but I cannot make it work. If I program a FilterReader all goes well:

import java.io.*;

class Filter extends FilterReader {
  Filter(Reader in) {
    super(in);
  }

  public int read() throws IOException {
    return 'A';
  }
}

public class TestFilter {
  public static void main(String[] args) throws IOException {
    Reader in = new Filter(new InputStreamReader(System.in));
    System.out.println((char)in.read());
  }
}

execution is A

but if I use FiterInputStream, execution blocks reading:

import java.io.*;

class Filter extends FilterInputStream {
  Filter(InputStream in) {
    super(in);
  }

  public int read() throws IOException {
    return 'A';
  }
}

public class TestFilter {
  public static void main(String[] args) throws IOException {
    Reader in = new InputStreamReader(new Filter(System.in));
    System.out.println((char)in.read());
  }
}

Upvotes: 1

Views: 271

Answers (3)

josseyj
josseyj

Reputation: 300

In the first case in.read() directly invokes Filter.read() method. In the second case in.read() invokes InputStreamReader.read().
Now we might expect it to delegate the call to Filter.read(). But InputStreamReader.read() implementation does something else - I dont understand what it is doing.
But eventually FilterInputStream.read(byte[], int, int) method is invoked, which waits for the user input. So to get the behavior you expect - I guess - we need to override this read method - as shown below.

import java.io.*;

class Filter extends FilterInputStream {
  Filter(InputStream in) {
    super(in);
  }

  public int read() throws IOException {
    return 'A';
  }

  @Override
    public int read(byte[] b, int off, int len) throws IOException {
      if(len == 0) {
          return 0;
      }
      b[off] = (byte) read();
      return 1;
     }

}

public class TestFilter {
  public static void main(String[] args) throws IOException {
    Reader in = new InputStreamReader(new Filter(System.in));
    System.out.println((char)in.read());
  }
}

Upvotes: 2

orangepips
orangepips

Reputation: 9971

In your second TestFilter replace

Reader in = new InputStreamReader(new Filter(System.in));

With

InputStream in = new Filter(System.in);

This will execute Filter.read() on the class you created sending "A" to System.out.

Upvotes: 0

assylias
assylias

Reputation: 328765

In the first code, your Reader is:

new Filter(new InputStreamReader(System.in));

and its read method is the one you have overriden:

public int read() throws IOException {
    return 'A';
}

In the second code, your Reader is:

new InputStreamReader(new Filter(System.in));

and the read method of your Filter is not used. The Reader instead waits on System.in so you have to type in something (+ ENTER) to get something read.

Upvotes: 2

Related Questions