问题描述
我正在网站学习平台上学习Java,他们拥有这个单元测试框架,在其中它们将System.out和System.in替换为其自己的输入/输出流版本,以检查数据并将其注入程序中进行测试。在进行一些本网站练习时,有一个练习以捷克语提供了文本,第一个测试用例针对带有以下字符的单词测试了我的输出:ř
好吧,我的测试失败了,因为我的输入将ř
替换为Y
。
试图理解原因,我意识到ř
具有Unicode值\u0159
,而Y
具有Unicode值\u0059
。以二进制表示,以两个字节表示,它们分别对应于:
ř 0000 0001 0101 1001
Y 0000 0000 0101 1001
您能发现问题吗?我确实立即发现了它。最重要的字节在该测试框架的内脏中丢失了。
经过一番挖掘,我发现该类扩展了InputStream
,它们用于替换System.in,并具有以下read()
@Override
public int read(byte[] b,int off,int len) throws IOException {
if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte) c;
int i = 1;
try {
for (; i < len; i++) {
if (c == '\n') {
break;
}
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte) c;
}
} catch (IOException ignored) {
}
return i;
}
结果表明,行int c = read();
获取输入String的下一个字符的整数值。
好吧,char ř
的十进制值345
超过了255,因此最高有效字节丢失了,上述方法用丢失数据的char填充了byte[] b
缓冲区。
经过长时间的语境化(对不起,我想尽可能地清楚)我问:
为了正确地将输入文本中的所有c
转换为字节数组,可以对InputStream的此子目录进行哪些操作?
我尝试了这个,但是对我来说似乎很俗气,因为这并没有真正读取逐字节读取的任何输入。我不知道。看起来很骗人,而且很泛泛:
@Override
public int read(byte[] b,int len) throws IOException {
if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte) c;
b[off + 1] = (byte) (c >> 8);
int i = 2;
try {
for (; i < len; i++) {
if (c == '\n') {
break;
}
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte) c;
++i;
b[off + i] = (byte) (c >> 8);
}
} catch (IOException ignored) {
}
return i;
}
这可以返回一个正确的数组,该数组代表输入中存在的所有字节,但是,最终的字节数组不会被解释为框架其余部分的两个字节组。
我真的超出了Java的能力来查明这个问题,因为我只是一个初学者,我用尽了所有工具来找到解决此问题的方法。
Here's my fork of said library.
Here's a direct link to the relevant class
很抱歉,很长的帖子。
干杯!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)