关于java:将字节写入文件时丢失数据

Data loss when writing bytes to a file

我在为学校作业设计一个弦压缩器,

有一个问题我好像解决不了。压缩数据正在使用一个文件编写器(由字节数组表示)写入一个文件。压缩算法返回一个输入流,因此数据流如下:

1
2
3
4
piped input stream
-> input stream reader
-> data stored in char buffer
-> data written to file with file writer.

现在,错误是,对于一些非常具体的字符串,字节数组中的第二个到最后一个字节是写错的。它总是相同的位值"111111 00"。

每次都是这个位值,总是从第二个字节到最后一个字节。

以下是代码中的一些示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  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".

你正在服用

1
2
3
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转换

1
 bytes1[] -> chars[] -> bytes2[]

在某些情况下,字节2将不同于字节1。

我建议更改代码以删除这些读卡器。或者指定ASCII编码以查看是否阻止了翻译。