Java 从读取器中删除或忽略字符

Java 从读取器中删除或忽略字符,java,Java,我正在将所有字符读入流中。我正在用inputStream.read阅读它。这是java.io.Reader inputStream。 在读入缓冲区时,如何忽略像@这样的特殊字符 代码 您可以实现从inputstream派生的自己的inputstream。然后重写读取方法,以便它们从流中过滤出特殊字符。您可以使用自定义的FilterReader private final void FillBuff() throws java.io.IOException { int i; if (maxNe

我正在将所有字符读入流中。我正在用inputStream.read阅读它。这是java.io.Reader inputStream。 在读入缓冲区时,如何忽略像@这样的特殊字符

代码


您可以实现从inputstream派生的自己的inputstream。然后重写读取方法,以便它们从流中过滤出特殊字符。

您可以使用自定义的
FilterReader

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;
 }
}
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;
    }
}
class YourFilterReader扩展了FilterReader{
@凌驾
public int read()引发IOException{
int-read;
做{
read=super.read();
}while(read=='@');
返回读取;
}
@凌驾
公共整数读取(char[]cbuf,int off,int len)引发IOException{
int read=super.read(cbuf、off、len);
如果(读取==-1){
返回-1;
}
int pos=关闭-1;
用于(int-readPos=off;readPos

资源:

关于同一主题:


所有这些读卡器、写卡器和流都实现了Decorator模式。每个装饰器向底层实现添加额外的行为和功能

满足您需求的解决方案可以是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;
  }

}
公共类FilterReader实现可读、可关闭的{
私有集黑名单=新HashSet();
私人读者;
公共过滤器读卡器(读卡器){
this.reader=读取器;
}
公共void addFilter(字符过滤){
黑名单。添加(过滤);
}
@凌驾
public void close()抛出IOException{reader.close();}
@凌驾
公共整数读取(char[]charBuf){
char[]temp=新字符[charBuf.length];
int charsRead=reader.read(temp);
int指数=-1;
如果(!(charsRead==-1)){
用于(字符c:temp){
如果(!blacklist.contains(c)){
charBuf[index]=c;
索引++;
}
}
}
收益指数;
}
}


注意-类
java.io.FilterReader
是一个具有零功能的装饰器。您可以扩展它,也可以忽略它,创建自己的装饰器(在本例中我更喜欢)

什么是specialCharacter方法?使用
read(char[])
方法,我认为您应该一直阅读,直到
charBuf
满为止。您的实现只读取下一个
charbuf.length
元素中的有效元素。
Set
的整体实现很好-也许我会包含另一个带有
Set
参数的构造函数-但这在这里并不是很重要。我会扩展
java.io.FilterReader
,将类保留为读卡器可能很有用,并明确地说,它是为过滤输入字符流而创建的读取器。多态性仍然可用。在您的例子中,您不能将类封装到另一个阅读器中,因为它不是另一个阅读器。Yikes-
Reader
不是一个接口,而是一个抽象类。更改了实现…
BufferedReader
也是-a
Reader
和has-a
Reader
。这是Reader/Writer/inputstreams/outputstreams的要点,你可以将它们全部封装起来。@Colin-我删除了这句愚蠢的话,我想提出一个不同的观点:通常我们用接口来实现这种模式,但不幸的是SUN决定实现一个抽象类,而不是
Reader
接口。是的,一个新的装饰师是最好的选择。只是一张便条。在第二种方法中,缺少参数。;)我认为循环中的第一行应该是
if(cbuf[readPos]='@'){
。现在测试的
read
变量在循环的每次迭代中都保持不变。
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;
  }

}