Hi Kim

The answer is no. It calls the read method of the "in" object who is an InputStream too (it is the source for the filter). In this case, it is about the same thing, as a FilterInputStream calls the correspondent method of its "in" member.

Let's say that you have written a filter "MyFilter" and an application uses it:
   InputStream myFile = new FileInputStream("myfile.txt");
   InputStream myIn = new MyFilter(myFile);

Supposing that MyFilter uses "super" to override the "read()" method. In this case:
   char ch = (char)myIn.read();
performs the following actions:
myIn.read() -calls-> super.read() who -calls-> in.read() (in other words myFile.read()).

If MyFilter uses "in.read()" then:
   myIn.read() ---> in.read() (myFile.read()).

It is not that it is one step shorter, but it allows more flexibility. In the case of "convert to upper", there it makes no difference. But imagine that it was you who written the BufferedInputStream. It must allow to read from a source InputStream (for e.g. a FileInputStream) but ensure that (for performance reasons), all reads are buffered.

Your implementation would be something like:

public class MyBufferedInputStream extends FilterInputStream {
   // inherits the constructor that sets the "in" member
   byte[] buffer = new byte[4096]; // 4KB buffer
   int position = buffer.length; // current position: beyond the buffer

   public byte read(){
       if ( position >= buffer.lenght){
in.read(buffer); // it never reads only a byte, it always reads a full buffer
           position = 0;
       }
       return buffer[position++]; // returns a byte
   }

   public void read(byte[] b, int off, int len){
       for ( int i = 0 ; i < len ; i++ )
           b[i+off] = this.read();
   }

   public void read(byte[] b){
       this.read(b, 0, b.length);
   }
}

In this way, the buffered filter always reads a buffer although it can return a byte-by-byte read (of course, the above implementation is not complete, it doesn't manage the "end of file" case). In order to do that, it doesn't call the "super" methods, but directly the methods of the "in" member or even its own (overridden) methods.

In the same way, for a Unicode UTF-8 compatible character reading, you might wish to build a filter that reads one or two or ... up to four bytes from the "in" in order to produce one Unicode valid character. It seems more logical to call the read() method of the "in" member than to repeatedly call the super.read().

The pattern for this kind of behavior is not the inheritance but the "wrapper": the wrapper class contains the wrapped object as a member. It is a largely used technique for various filters (for e.g. servlet filters).

As I said, for simple cases the inheritance may work as well. The wrapper is logically more appropriate in complex cases.

Hope it helps
Mihai


Kim Ching Koh a écrit :
Hi Mihai,
Here is confused part, in my override method, calling in.read() actually invoke/calls super class (FilterInputStream) read()? Regards
Kim

On Tue, Jun 1, 2010 at 2:41 PM, Mihai DINCA <[email protected] <mailto:[email protected]>> wrote:

    Hi Kim

    You are right. In fact there are three methods to override. For e.g.:
    -- Your Filter, inheriting FilterInputStream, has a constructor
    that sets the "in" member. As it is protected, you can access it
    from your derived class
    -- Your overridden read() just makes something like char c =
    Character.toUpperCase((char)in.Read());
    -- The read(byte[] b) calls in.read(b), then converts all the
    bytes (assumed to be characters) to upper cases
    -- The read(byte[] b, int off, int len) calls in.read(b, off, len)
    then converts to upper cases only the bytes between the offset and
    offset + len. Something like:
        for ( int i = 0 ; i < len ; i++ ){
            b[off + i] = (byte)Character.toUpeerCase((char)b[off + i]);

        }

    Hope it helps
    Mihai


    Kim Ching Koh a écrit :
    Hi Mihai,
Not sure what do you mean by read a buffer, do you mean *read* <https://mail.google.com/mail/html/java/io/FilterInputStream.html#read%28byte%5B%5D%29>(byte[] b)? How about *read*
    
<https://mail.google.com/mail/html/java/io/FilterInputStream.html#read%28byte%5B%5D,%20int,%20int%29>(byte[]
 b,
int off, int len)? Need to override too? read(byte[] b) seems to be calling read(byte[] b, int off, int
    len), so we maybe able to to override read(byte[] b) but I am not
    sure how to override read(byte[] int off, int len)
In Exercise 8, read(byte[] int off int len) seem to calling
    itself?  How does this work?
    public int read(byte[] b, int off, int len) throws IOException {
            len = in.read(b, off, len);
            if (len != -1) {
                cksum.update(b, off, len);
            }
            return len;
        }
    Thanks.
    KC


    On Wed, May 26, 2010 at 2:15 PM, Mihai DINCA <[email protected]
    <mailto:[email protected]>> wrote:

        Hi Kim

        The idea of the topic is that InputStreams and OutputStreams
        are based on layers. Once you have an InputStream, you can
        read from it through a filter. For e.g., you can write
        InputStream in = new BufferedInputStream( new
        FileInputStream("filename.txt"));. The FileInputStream is the
        actual source of data, but you read it through a
        BufferedInputStream that allows a (more efficient) buffered
        read from the source, still allowing a byte-by-byte access.

        You can extend all this and write:
            InputStream in = new MyFilter1Stream( new
        MyFilter2Stream( new MyFilter3Stream( new
        FileInputStream("myfile.txt"))));
        where each filter adds something to the reading process. One
        of them might, for e.g., convert all the input characters to
        capital letters.

        The same idea applies to OutputStreams. You can have your own
        filter in the chain that converts, for e.g., all the dirty
        words in "***" strings.

        The homework is based by a lab exercise that reads from a
        file, through and InputStream, and echoes its contents to
        another one, through an OutputStream and asks to write other
        a filter for the input or a filter for the output that
        converts all letters to capital letters.

        To create your own FilterInputStream, you must override both
        read methods (the one that read on byte and the other that
        reads a buffer) so that they read from the source InputStream
        (one byte or a buffer), then convert the input to capital
        letters. Analogically, to create your own FilterOutputStream
        yo must override all the write methods.

        Hope it helps
        Mihai



        Kim Ching Koh a écrit :
        Hi,
Anyone has done this homework can advise? Regards
        KC

        On Tue, May 25, 2010 at 2:53 PM, kc <[email protected]
        <mailto:[email protected]>> wrote:

            Hi,

            I am not too sure what is the requirement of the
            homework for java
            stream I/O, is it just to overide read() in the
            ChangeToUpperCaseInputStream class so it will convert
            and return to
            uppercase?


            1. The homework is to either modify
            FilterInputOutputStream NetBeans
            project you've done in Exercise 8 above or create a new
            project as
            following.  (You might want to create a new project by
            copying the
            FilterInputOutputStream project.  You can name the
            homework project in
            any way you want but here I am going to call it
            MyIOStreamProject.)
            Write ChangeToUpperCaseInputStream class, which extends
            FilterInputStream.
            Write ChangeToUpperCaseOutputStream class, which extends
            FilterOutputStream.

            Use either ChangeToUpperCaseInputStream class or
            ChangeToUpperCaseOutputStream class to convert the
            characters read to
            upper case.

            Regards
            KC

            --
            To post to this group, send email to
            [email protected]
            <mailto:[email protected]>
            To unsubscribe from this group, send email to
            [email protected]
            <mailto:javaprogrammingwithpassion%[email protected]>
            For more options, visit this group at
            http://groups.google.com/group/javaprogrammingwithpassion?hl=en


-- To post to this group, send email to
        [email protected]
        <mailto:[email protected]>
        To unsubscribe from this group, send email to
        [email protected]
        <mailto:[email protected]>
        For more options, visit this group at
        http://groups.google.com/group/javaprogrammingwithpassion?hl=en


-- To post to this group, send email to
    [email protected]
    <mailto:[email protected]>
    To unsubscribe from this group, send email to
    [email protected]
    <mailto:[email protected]>
    For more options, visit this group at
    http://groups.google.com/group/javaprogrammingwithpassion?hl=en



--
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaprogrammingwithpassion?hl=en

Reply via email to