我正在为一项学校作业开发一个字符串压缩器,
有一个我似乎无法解决的错误。使用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);
}
例如,触发它的字符串是“hello and good evenin”。
我试图迭代字节数组并逐个编写,但没有用。
值得注意的是,当我尝试使用算法本身的输出流写入文件时,它工作正常。这个设计不是我的选择。
所以我不确定我在这里做错了什么。
答案 0 :(得分:0)
考虑到你在说:
现在,错误是,对于一些非常具体的字符串,第二个 字节数组中的最后一个字节写错了。而且它总是一样的 位值" 11111100"。
你正在
binary stream (the compressed data)
-> reading it as chars
-> then writing it as chars.
你正在将字节转换为字符而没有明确定义编码。
我说问题是你的InputStreamReader
正在以你不期望的方式翻译某些字节序列。
请记住,在像utf-8这样的编码中,两个或三个字节可能会成为一个字符。
您指出的字节模式(11111100
)是utf-8转义码(1111110x
)之一,这不是巧合。检查此维基百科table,您会发现uft-8具有破坏性,因为如果一个字节以:1111110x
开头,则下一个必须以10xxxxxx
开头。
意思是如果使用utf-8转换
bytes1[] -> chars[] -> bytes2[]
在某些情况下,bytes2将与bytes1不同。
我建议您更改代码以删除这些读者。或者指定ASCII编码以查看是否会阻止翻译。
答案 1 :(得分:0)
我通过使用Base64对字节进行编码和解码来解决这个问题。