如何读取Java中的字符串流丢弃非法字符?

时间:2013-05-24 15:25:54

标签: java parsing text

我必须解析来自TCP连接的字节流,该连接应该只给我可打印的字符,但实际上并非总是这样。我在那里看到了一些二进制零,在某些字段的开头和结尾。我无法控制数据源,我需要处理“脏”行。如果我可以过滤掉无效字符,那就没问题了。相关代码如下:

srvr = new ServerSocket(myport);
skt = srvr.accept();
// Tried with no encoding argument too
in = new Scanner(skt.getInputStream(), "ISO-8859-1");
in.useDelimiter("[\r\n]");
for (;;) {
    String myline = in.next();
    if (!myline.equals(""))
        ProcessRecord(myline);
}

我在每条有“污垢”的行都会遇到异常。什么是过滤掉无效字符的好方法,同时仍然能够获得字符串的其余部分?

3 个答案:

答案 0 :(得分:3)

您必须将InputStream包装在CharsetDecoder中,并定义一个空的错误处理程序:

//let's create a decoder for ISO-8859-1 which will just ignore invalid data
CharsetDecoder decoder=Charset.forName("ISO-8859-1").newDecoder();
decoder.onMalformedInput(CodingErrorAction.IGNORE);
decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
//let's wrap the inputstream into the decoder
InputStream is=skt.getInputStream();
in = new Scanner(decoder.decode(is));

您还可以使用自定义CodingErrorAction并在编码错误时定义自己的操作。

答案 1 :(得分:1)

最纯粹的解决方案是过滤InputStream(二进制字节级I / O)。

in = new Scanner(new DirtFilterInputStream(skt.getInputStream()), "Windows-1252");

public class DirtFilterInputStream extends InputStream {

    private InputStream in;

    public DirtFilterInputStream(InputStream in) {
        this.in = in;
    }

    @Override
    public int read() throws IOException {
        int ch = in.read();
        if (ch != -1) {
            if (ch == 0) {
                ch = read();
            }
        }
        return ch;
    }

}

(您需要覆盖所有方法,并委托给原始流。) Windows-1252是Windows Latin-1,扩展的Latin 1,ISO-8859-1,使用0x80 - 0xBF。

答案 2 :(得分:0)

我完全偏离了基地。我得到“脏”字符串没有问题(不,我没有选项来清理数据源,它来自一个封闭的系统,我不得不笑着处理它)但是试图将它们存储在PostgreSQL中是得到的我是例外。这意味着我可以在处理之前完全自由地清理它。