我正在尝试编写一个可以压缩数据的类。下面的代码失败了(没有抛出异常,但是目标 .gz 文件是空的。)
此外:我不想像在所有示例中那样直接生成 .gz 文件。我只想获取压缩数据,以便我可以在将数据写入文件之前对其进行加密。
如果我直接写入文件,一切正常:
import java.io.*;
import java.util.zip.*;
import java.nio.charset.*;
public class Zipper
{
public static void main(String[] args)
{
byte[] dataToCompress = "This is the test data."
.getBytes(StandardCharsets.ISO_8859_1);
GZIPOutputStream zipStream = null;
FileOutputStream fileStream = null;
try
{
fileStream = new FileOutputStream("C:/Users/UserName/Desktop/zip_file.gz");
zipStream = new GZIPOutputStream(fileStream);
zipStream.write(dataToCompress);
fileStream.write(compressedData);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{ zipStream.close(); }
catch(Exception e){ }
try{ fileStream.close(); }
catch(Exception e){ }
}
}
}
但是,如果我想将它“绕过”到字节数组流,它不会产生单个字节 - compressedData
始终为空。
import java.io.*;
import java.util.zip.*;
import java.nio.charset.*;
public class Zipper
{
public static void main(String[] args)
{
byte[] dataToCompress = "This is the test data."
.getBytes(StandardCharsets.ISO_8859_1);
byte[] compressedData = null;
GZIPOutputStream zipStream = null;
ByteArrayOutputStream byteStream = null;
FileOutputStream fileStream = null;
try
{
byteStream = new ByteArrayOutputStream(dataToCompress.length);
zipStream = new GZIPOutputStream(byteStream);
zipStream.write(dataToCompress);
compressedData = byteStream.toByteArray();
fileStream = new FileOutputStream("C:/Users/UserName/Desktop/zip_file.gz");
fileStream.write(compressedData);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try{ zipStream.close(); }
catch(Exception e){ }
try{ byteStream.close(); }
catch(Exception e){ }
try{ fileStream.close(); }
catch(Exception e){ }
}
}
}
原文由 Master-Jimmy 发布,翻译遵循 CC BY-SA 4.0 许可协议
问题是您没有关闭
GZIPOutputStream
。在您关闭它之前,输出将是不完整的。您只需要在读取字节数组 之前 关闭它。您需要重新排序
finally
块才能实现此目的。我不建议将流变量初始化为
null
,因为这意味着你的finally
块也可以抛出NullPointerException
另请注意,您可以声明
main
抛出IOException
(这样就不需要最外面的try
语句。)从
zipStream.close();
吞下异常没有什么意义,因为如果它抛出异常,你将没有有效的 .gz 文件(所以你不应该继续编写它。)此外,我不会吞下来自
byteStream.close();
的异常,但出于不同的原因 - 它们永远不应该被抛出(即你的 JRE 中有一个错误,你会想知道那个。)