我正在尝试从zipFile读取UTF-8文件,结果证明这是一个重大挑战。
这里我将String压缩为一个字节数组,以保存到我的数据库。
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zo = new ZipOutputStream( bos );
zo.setLevel(9);
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(bos, Charset.forName("utf-8"))
);
ZipEntry ze = new ZipEntry("data");
zo.putNextEntry(ze);
zo.write( s.getBytes() );
zo.close();
writer.close();
return bos.toByteArray();
这就是我读回字符串的方式:
ZipInputStream zis = new ZipInputStream( new ByteArrayInputStream(bytes) );
ZipEntry entry = zis.getNextEntry();
byte[] buffer = new byte[2048];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int size;
while ((size = zis.read(buffer, 0, buffer.length)) != -1) {
bos.write(buffer, 0, size);
}
BufferedReader r = new BufferedReader( new InputStreamReader( new ByteArrayInputStream( bos.toByteArray() ), Charset.forName("utf-8") ) );
StringBuilder b = new StringBuilder();
while (r.ready()) {
b.append( r.readLine() ).append(" ");
}
我回到这里的字符串丢失了UTF8字符!
更新1: 我更改了代码,以便将原始String的字节数组与从zipfile读回的字节数组进行比较,并且它们非常匹配!所以它可能是我在拥有字节之后构建字符串的方式。
Arrays.equals(已转换,orgi)
答案 0 :(得分:2)
你的问题出现在写作中,假设s
是String
,你有:
zo.write( s.getBytes() );
但是,无论默认编码是什么,它都会将s
转换为字节。您将要使用UTF-8进行转换:
zo.write( s.getBytes("utf-8") );
您观察到原始字节与未压缩字节相同是有意义的,因为原始写入数据是问题的根源。
请注意,您已声明writer
流但您实际上从未将其用于任何内容(在此上下文中也不应该这样做,因为写入它只会将未压缩的字符串数据写入同一个流{{1}您的bos
写入的内容)。看起来你可能会混淆自己在这里尝试一些不同的东西,你应该摆脱ZipOutputStream
。
答案 1 :(得分:1)
首先,BufferedReader#ready()
不是阅读输入的好指标。
其次,您正在使用
b.append( r.readLine() ).append(" ");
总是在每次迭代时添加" "
。由此产生的String
值必然与原始值不同。
第三,shout out to Jason C about your BufferedWriter
not doing anything.