【问题标题】:Compress a string to gzip in Java在Java中将字符串压缩为gzip
【发布时间】:2025-12-26 22:00:16
【问题描述】:
public static String compressString(String str) throws IOException{
    if (str == null || str.length() == 0) {
        return str;
    }
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    GZIPOutputStream gzip = new GZIPOutputStream(out);
    gzip.write(str.getBytes());
    gzip.close();
    Gdx.files.local("gziptest.gzip").writeString(out.toString(), false);
    return out.toString();
}

当我将该字符串保存到文件中并在 unix 中运行 gunzip -d file.txt 时,它会抱怨:

gzip: gzip.gz: not in gzip format

【问题讨论】:

  • 为什么不直接使用FileOutputStream (in place of the ByteArrayOutputStream)?你有没有尝试过会发生什么?
  • 是libgdx,是一个跨平台的游戏开发库。我只是将其写入文件以进行故障排除。我实际上一直在尝试通过 http POST 请求将字符串发送到我的烧瓶服务器,但服务器端抱怨该字符串不是有效的 gzip。
  • 我猜问题是您将压缩数据转换为字符串。我认为您应该将结果视为字节[]。 libgdx 可以将 byte[] 写入文件吗?
  • 可以的。试试 Gdx.files.local("gziptest.gzip").writeBytes(out.getBytes(), false)。会发生什么?

标签: java gzip gunzip


【解决方案1】:

尝试使用BufferedWriter

public static String compressString(String str) throws IOException{
if (str == null || str.length() == 0) {
    return str;
}

BufferedWriter writer = null;

try{
    File file =  new File("your.gzip")
    GZIPOutputStream zip = new GZIPOutputStream(new FileOutputStream(file));

    writer = new BufferedWriter(new OutputStreamWriter(zip, "UTF-8"));

    writer.append(str);
}
finally{           
    if(writer != null){
     writer.close();
     }
  }
 }

关于您的代码示例尝试:

public static String compressString(String str) throws IOException{
if (str == null || str.length() == 0) {
    return str;
}
ByteArrayOutputStream out = new ByteArrayOutputStream(str.length());
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(str.getBytes());
gzip.close();

byte[] compressedBytes = out.toByteArray(); 

Gdx.files.local("gziptest.gzip").writeBytes(compressedBytes, false);
out.close();

return out.toString(); // I would return compressedBytes instead String
}

【讨论】:

  • 这是一个有效的 gzip 对象。我真的很想返回一个字符串。我可以绕过写文件吗?
  • 你的例子先试试:ByteArrayOutputStream out = new ByteArrayOutputStream(str.length());
  • 看看我在上面发布的编辑,我修改了你的代码
  • 那行得通。在某些时候,我必须将其转换为字符串以发送到我的烧瓶应用程序 - 为什么您建议以 byte[] 的形式返回?
  • 因为我认为它不可读的字符串,IDK 你想用它做什么。如果你发送byte[]你可以在解压后返回
【解决方案2】:

试试看:

//...

String string = "string";

FileOutputStream fos = new FileOutputStream("filename.zip");

GZIPOutputStream gzos = new GZIPOutputStream(fos);
gzos.write(string.getBytes());
gzos.finish();

//...

【讨论】:

    【解决方案3】:

    使用 FileOutputStream 保存字节

    FileOutputStream fos = new FileOutputStream("gziptest.gz");
    fos.write(out.toByteArray());
    fos.close();
    

    out.toString() 看起来很可疑,结果将是不可读的,如果你不在乎那为什么不返回 byte[],如果你在乎的话,它看起来像 hex 或 base64 字符串更好。

    【讨论】:

    • 同意,我会从out.toByteArray()返回byte[]