5

i am reading all characters into stream. I am reading it with inputStream.read. This is java.io.Reader inputStream. How can i ignore special characters like @ when reading into buffer.

code

private final void FillBuff() throws java.io.IOException
  {
     int i;
     if (maxNextCharInd == 4096)
        maxNextCharInd = nextCharInd = 0;

     try {
        if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
                                            4096 - maxNextCharInd)) == -1)
        {
           inputStream.close();
           throw new java.io.IOException();
        }
        else
           maxNextCharInd += i;
        return;
     }
     catch(java.io.IOException e) {
        if (bufpos != 0)
        {
           --bufpos;
           backup(0);
        }
        else
        {
           bufline[bufpos] = line;
           bufcolumn[bufpos] = column;
        }
        throw e;
     }
  }
bombac
  • 287
  • 1
  • 3
  • 7

4 Answers4

9

You can use a custom FilterReader.

class YourFilterReader extends FilterReader{
    @Override
    public int read() throws IOException{
        int read;
        do{
            read = super.read();
        } while(read == '@');

        return read; 
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException{
        int read = super.read(cbuf, off, len);

        if (read == -1) {
            return -1;
        }

        int pos = off - 1;
        for (int readPos = off; readPos < off + read; readPos++) {
            if (read == '@') {
                continue;
            } else {
                pos++;
            }

            if (pos < readPos) {
                cbuf[pos] = cbuf[readPos];
            }
        }
        return pos - off + 1;
    }
}

Resources :

On the same topic :

Community
  • 1
  • 1
Colin Hebert
  • 91,525
  • 15
  • 160
  • 151
5

All those readers, writers and streams implement the Decorator pattern. Each decorator adds additional behaviour and functionality to the underlying implementation.

A solution for you requirement could be a FilterReader:

public class FilterReader implements Readable, Closeable {
  private Set<Character> blacklist = new HashSet<Character>();
  private Reader reader;      

  public FilterReader(Reader reader) {
    this.reader = reader;
  }

  public void addFilter(char filtered) {
    blacklist.add(filtered);
  }

  @Override
  public void close() throws IOException {reader.close();}

  @Override
  public int read(char[] charBuf) {
    char[] temp = new char[charBuf.length];
    int charsRead = reader.read(temp);
    int index = -1;
    if (!(charsRead == -1)) {
      for (char c:temp) {
        if (!blacklist.contains(c)) {
          charBuf[index] = c;
          index++;
         }
      }
    }
    return index;
  }

}

Note - the class java.io.FilterReader is a decorator with zero functionality. You can extend it or just ignore it and create your own decorator (which I prefer in this case).

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
  • With the `read(char[])` method, I think you should keep reading until the `charBuf` is full. Your implementation just reads the valid elements in the next `charbuf.length` elements. Nice implementation overall with the `Set` - perhaps I'd include another constructor with a `Set` parameter - but that's not really that important here. – Noel M Aug 31 '10 at 08:25
  • I would extend `java.io.FilterReader`, it could be useful to keep your class as a Reader, and explicitly say that it's a reader created to filter an input character stream. And polymorphism would still be available. And in your case, you can't encapsulate your class into another Reader, because it's not another Reader. – Colin Hebert Aug 31 '10 at 08:37
  • Yikes - `Reader` is not an interface but an abstract class. Changed the implementation... – Andreas Dolk Aug 31 '10 at 08:41
  • `BufferedReader` also **is-a** `Reader` and **has-a** `Reader`. It's the point of readers/writers/inputstreams/outputstreams you can encapsulate them all. – Colin Hebert Aug 31 '10 at 09:34
  • @Colin - I deleted the silly sentence, I wanted to make a different point: usually we do this pattern with interfaces but unfortunatly SUN decided to implement an abstract class instead of a `Reader` interface. – Andreas Dolk Aug 31 '10 at 10:44
0

You could implement an own inputstream derived from InputStream. Then override the read methods so that they filter a special character out of the stream.

Marc-Christian Schulze
  • 3,154
  • 3
  • 35
  • 45
0
private final void FillBuff() throws java.io.IOException
{
 int i;
 if (maxNextCharInd == 4096)
    maxNextCharInd = nextCharInd = 0;

 try {
    Reader filterReader = new FilterReader(inputStream) {
        public int read() {
            do {
                result = super.read();
            } while (specialCharacter(result));
            return result;
        }
    };
    if ((i = filterReader.read(nextCharBuf, maxNextCharInd,
                                        4096 - maxNextCharInd)) == -1)
    {
       inputStream.close();
       throw new java.io.IOException();
    }
    else
       maxNextCharInd += i;
    return;
 }
 catch(java.io.IOException e) {
    if (bufpos != 0)
    {
       --bufpos;
       backup(0);
    }
    else
    {
       bufline[bufpos] = line;
       bufcolumn[bufpos] = column;
    }
    throw e;
 }
}
gpeche
  • 21,974
  • 5
  • 38
  • 51