我必须解析来自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);
}
我在每条有“污垢”的行都会遇到异常。什么是过滤掉无效字符的好方法,同时仍然能够获得字符串的其余部分?
答案 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中是得到的我是例外。这意味着我可以在处理之前完全自由地清理它。