我在为学校作业设计一个弦压缩器,
有一个问题我好像解决不了。压缩数据正在使用一个文件编写器(由字节数组表示)写入一个文件。压缩算法返回一个输入流,因此数据流如下:
piped input stream
-> input stream reader
-> data stored in char buffer
-> data written to file with file writer.
现在,错误是,对于一些非常具体的字符串,字节数组中的第二个到最后一个字节是写错的。它总是相同的位值"111111 00"。
每次都是这个位值,总是从第二个字节到最后一个字节。
以下是代码中的一些示例:
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"。
我试图迭代字节数组并逐个写入它们,但没有帮助。
值得注意的是,当我尝试使用算法本身的输出流写入文件时,它工作得很好。这个设计不是我的选择。
所以我不太确定我在这里做错了什么。
我通过用base64对字节进行编码和解码来解决这个问题。
考虑到你在说:
Now, the bug is, that with some very specific strings, the second to
last byte in the byte array is written wrong. and it's always the same
bit values"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编码以查看是否阻止了翻译。
经过一些测试,编码(或缺少编码)肯定是这里的问题。我正在尝试用ISO-8859-1编写字符。到目前为止还没有运气。
你为什么要把这个写成字符?它是二进制数据。