将字节写入文件时数据丢失

时间:2015-05-01 13:09:54

标签: java string file stream compression

我正在为一项学校作业开发一个字符串压缩器,

有一个我似乎无法解决的错误。使用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”。

我试图迭代字节数组并逐个编写,但没有用。

值得注意的是,当我尝试使用算法本身的输出流写入文件时,它工作正常。这个设计不是我的选择。

所以我不确定我在这里做错了什么。

2 个答案:

答案 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对字节进行编码和解码来解决这个问题。