GZIP吃了换行符

时间:2013-10-10 15:45:45

标签: java gzip gzipinputstream gzipoutputstream

我有以下用于压缩和解压缩字符串的代码。

public static byte[] compress(String str)
{
    try
    {
        ByteArrayOutputStream obj = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(obj);
        gzip.write(str.getBytes("UTF-8"));
        gzip.close();
        return obj.toByteArray();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    return null;
}

public static String decompress(byte[] bytes)
{
    try
    {
        GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes));
        BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
        StringBuilder outStr = new StringBuilder();
        String line;
        while ((line = bf.readLine()) != null)
        {
            outStr.append(line);
        }
        return outStr.toString();
    }
    catch (IOException e)
    {
        return e.getMessage();
    }
}

我在windows上压缩成字节数组,然后通过套接字将字节数组发送到linux并在那里解压缩。然而,在解压缩时,似乎我的所有换行符都消失了 所以我认为问题是linux与windows的关系。但是我尝试在使用它的Windows上编写一个简单的程序,并发现新行仍然没有了 任何人都可以了解导致它的原因吗?我无法弄清楚任何解释。

2 个答案:

答案 0 :(得分:6)

我认为问题在于:

while ((line = bf.readLine()) != null)
    {
        outStr.append(line);
    }

readLine查看换行符,但不包含在line

的返回值中

问题可能比你想象的还要糟糕。

readLine()获取所有字符,但不包括换行符(或各种返回和换行符)或文件末尾。所以你不知道你得到的最后一行是否有一个新行。

这可能无关紧要,如果是这样,你可以在另一个追加后添加:

outStr.append('\n');

某些文件可能会以文件末尾的额外行结束。

如果确实重要,您需要使用read()然后输出您收到的所有字符。在这种情况下,你最终可能会得到臭名昭着的“最后一行是什么?”您在Windows,Linux和MacOS之间提到的问题以及它们使用返回行和换行符的不同组合的方式。

答案 1 :(得分:5)

GZIP不是“吃”换行符。

这是代码:

    while ((line = bf.readLine()) != null)
    {
        outStr.append(line);
    }

readLine()方法读取一行(直到并包括行终止序列),然后返回而不换行符。然后,将其附加到outStr ... ,而不用替换已剥离的行终止。

但即使您更换了线路终端,也无法保证保留已使用的实际线路终端序列...如果您这样做。

我建议您使用readLine()来电替换read()来电;即读取然后一次缓冲一个字符的数据。它同时解决了两个问题。它甚至可能更快,因为你避免了组装行字符串的不必要的开销。

相关问题