我正在为学校作业开发字符串压缩器
有一个错误我似乎解决不了。压缩数据使用FileWriter写入文件,该文件由字节数组表示。压缩算法返回一个输入流,因此数据流如下:
piped input stream
-> input stream reader
-> data stored in char buffer
-> data written to file with file writer.
现在,错误是,对于一些非常特定的字符串,字节数组中倒数第二个字节写错了。并且它总是相同的比特值"11111100"。
每次都是这个位值,并且总是倒数第二个字节。
以下是代码中的一些示例:
InputStream compress(InputStream){
//...
//...
PipedInputStream pin = new PipedInputStream();
PipedOutputStream pout = new PipedOutputStream(pin);
ObjectOutputStream oos = new ObjectOutputStream(pout);
oos.writeObject(someobject);
oos.flush();
DataOutputStream dos = new DataOutputStream(pout);
dos.writeFloat(//);
dos.writeShort(//);
dos.write(SomeBytes); // ---Here
dos.flush();
dos.close();
return pin;
}
void write(char[] cbuf, int off, int len){
//....
//....
InputStreamReader s = new InputStreamReader(
c.compress(new ByteArrayInputStream(str.getBytes())));
s.read(charbuffer);
out.write(charbuffer);
}
触发它的字符串是"你好,晚上好"。
我尝试过对字节数组进行迭代并逐个写入,但没有帮助。
同样值得注意的是,当我尝试使用算法本身的输出流写入文件时,它运行良好。顺便说一句,这个设计不是我的选择。
所以我真的不确定我在这里做错了什么。
考虑到你说的是:
现在,错误是,对于一些非常特定的字符串字节数组中的最后一个字节写错了。它总是一样的位值"11111100"。
您正在进行
binary stream (the compressed data)
-> reading it as chars
-> then writing it as chars.
并且您在没有明确定义编码的情况下将字节转换为字符。
我想说,问题是InputStreamReader
正在以一种你意想不到的方式翻译一些字节序列。
请记住,在utf-8这样的编码中,两个或三个字节可能会变成一个字符。
你指出的字节模式(11111100
)是utf-8转义码(1111110x
)之一,这不可能是巧合。检查上的这个维基百科表,你会发现uft-8是破坏性的,因为如果一个字节以:1111110x
开头,那么下一个字节必须以10xxxxxx
开头。
这意味着如果使用utf-8转换
bytes1[] -> chars[] -> bytes2[]
在某些情况下,字节2将不同于字节1。
我建议您更改代码以删除这些读卡器。或者指定ASCII编码以查看是否阻止翻译。
我通过使用Base64对字节进行编码和解码来解决这个问题。