1

我必须解析来自 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);
}

我在每行有“污垢”的地方都有一个例外。什么是过滤掉无效字符同时仍然能够获取字符串的其余部分的好方法?

4

3 回答 3

4

您必须将您的包装InputStream在 a 中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并定义自己的操作。

于 2013-05-24T15:38:38.627 回答
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。

于 2013-05-24T15:38:53.900 回答
0

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

于 2013-05-24T15:40:00.037 回答