【问题标题】:How to GZIP files on Java and send it through the OutputStream如何在 Java 上 GZIP 文件并通过 OutputStream 发送
【发布时间】:2016-03-24 17:59:46
【问题描述】:

我正在使用 GZIPOutputStream 类对图像进行 GZIP 压缩。当我尝试通过 OutputStream 发送 GZIP 文件时收到损坏的文件。我知道如何 GZIP 到 FileOutputStream。以下代码完美运行:

Static private void GZIPCompress(String fileName)
{
        File file = new File(fileName);
        FileInputStream fis = new FileInputStream(file);
        byte[] data = new byte[(int) file.length()];

        fis.read(data); 
        FileOutputStream fos = new FileOutputStream(fileName + ".gz");
        GZIPOutputStream gzos = new GZIPOutputStream(fos); 
        gzos.write(data);
        fos.close();
        fis.close();
 }

输出文件是 myfile.png.gz 并具有以下详细信息

myfile.png.gz:gzip 压缩数据,来自 FAT 文件系统(MS-DOS、OS/2、 新台币)

我的问题是当我尝试 GZIP 文件并将其发送到 OutputStream 时。由于我正在使用服务器,因此我从服务器调用它并且我正在使用套接字。

Static void SendGZIPFile(String fileName, OutputStream os)
{
        DataOutputStream dos = new DataOutputStream(os);
        File file = new File(fileName);
        FileInputStream fis = new FileInputStream(file);
        byte[] data = new byte[(int) file.length()];
        byte[] dataAux = new byte[(int) file.length()];
        dos.writeBytes("HTTP/1.1 200 OK\r\n");
        dos.writeBytes("Content-Type: application/x-gzip \r\n");
        dos.writeBytes("Content-Disposition: form-data; filename="+"\""+fileName+".gz"+"\""+"\n");
        dos.writeBytes("\r\n\r\n");
        dos = new DataOutputStream(new GZIPOutputStream(os));
        fis.read(data);
        dos.write(data);
        dos.close();
        fis.close();
        gzos.close();
}

我得到的是一个损坏的 GZIP 文件,其中不包含任何内容:这里是详细信息

myfile.gz 数据

我认为我在 GZipping 时做错了什么,因为我注意到 详细信息 之间的差异。我使用以下命令来获取它:file myfile.gz

【问题讨论】:

  • 只是出于兴趣,为什么要手动执行 HTTP 而不是使用库/框架?
  • PNG 已经被压缩,因此尝试 GZIP 可能会使它变大。
  • 能否请您也显示调用SendGZIPFile(fileName, outputStream)的部分?

标签: java sockets server gzip


【解决方案1】:

在关闭dos 之前刷新gzos。或者先关闭gzos

【讨论】:

  • 请注意我的问题在于第二个函数 sendGZIPFiles 并且我没有变量 gzos。
  • 对不起,gzos.close(); 让我感到困惑
  • 您的行终止符似乎有问题,请尝试删除 content-disposition 行中的 \n。
  • 谢谢你是因为\n,我删除了它现在正在压缩!!
【解决方案2】:

除了您的代码缺乏基本的正确性(您可能不应该在代码中实现 HTTP,更聪明的人过去已经这样做了),我认为问题在于您没有正确复制数据。相反,您应该像这样在循环中进行复制:

byte[] buf = new byte[1024];
int len;
while((len = fis.read(buf)) != -1)
{
    dos.write(buf, 0, len);
}

或者您可以只使用 Apache Commons IO:

IOUtils.copy(fis, dos);

【讨论】:

    猜你喜欢
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 2020-05-29
    • 2013-01-01
    • 2012-07-25
    相关资源
    最近更新 更多