2010-08-11 579 views
2

我正在C#winforms应用程序中使用GZipStream类实现运行长度编码。包含换行符的十六进制字符串的运行长度编码

数据被提供为一系列由换行字符分开,像这样的字符串:

FFFFFFFF 
FFFFFEFF 
FDFFFFFF 
00FFFFFF 

之前压缩,我的字符串转换为字节数组,但如果换行字符都存在这样失败。

每个换行都很重要,但我不确定如何在编码中保留它们的位置。

这里是我使用的转换为字节数组的代码:

private static byte[] HexStringToByteArray(string _hex) 
{ 
    _hex = _hex.Replace("\r\n", ""); 
    if (_hex.Length % 2 != 0) throw new FormatException("Hex string length must be divisible by 2."); 
    int l = _hex.Length/2; 
    byte[] b = new byte[l]; 
    for (int i = 0; i < l; i++) 
    b[i] = Convert.ToByte(_hex.Substring(i * 2, 2), 16); 
    return b; 
} 

Convert.ToByte如果换行不删除抛出一个出现FormatException,随着信息:“其他无法分析的字符是在结束的字符串。“这并不令我感到意外。

确保换行符可以正确包含的最佳方法是什么?

注意我要补充的是,压缩版本字符串本身必须是可以被包含在XML文档中的字符串。

编辑:

我试图简单地将字符串转换为字节数组,而不在其上进行任何二进制转换,但我仍然有压缩的麻烦。以下是相关的方法:

private static byte[] StringToByteArray(string _s) 
    { 
     Encoding enc = Encoding.ASCII; 
     return enc.GetBytes(_s); 
    } 

    public static byte[] Compress(byte[] buffer) 
    { 
     MemoryStream ms = new MemoryStream(); 
     GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true); 
     zip.Write(buffer, 0, buffer.Length); 
     zip.Close(); 
     ms.Position = 0; 

     byte[] compressed = new byte[ms.Length]; 
     ms.Read(compressed, 0, compressed.Length); 

     byte[] gzBuffer = new byte[compressed.Length + 4]; 
     Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length); 
     Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4); 
     return gzBuffer; 
    } 

回答

2

首先:你肯定只是压缩文本并没有给太多相同的结果压缩“转换成二进制”的形式?

假设你想转换为二进制先走,我可以建议两个选项:

  • 在每一行的开始,写一个数字,说明有多少字节的线。然后当你解压时,你读取并转换那么多字节,然后写一个换行符。如果你知道每行总是小于256字节长,你可以把它表示为单个字节。否则,你可能需要一个更大的固定大小,或者一些可变大小的编码(例如,“当最高位被设置时,这仍然是数字的一部分”) - 后者很快就会变得毛茸茸的。
  • 或者,通过将其表示为(比如)0xFF,0x00来“转义”换行符。你会然后需要逃脱一个真正的0xFF作为(说)0xFF 0xFF。当你读取数据时,如果读取0xFF,你会读取下一个字节,以确定它是代表新行还是真正的0xFF。

编辑:我相信你原来的方法是根本上有缺陷。无论你从GZipStream得到的是而不是文本,并且不应该被视为使用Encoding的文本。但是,通过调用Convert.ToBase64String,您可以非常轻松地将其转换为 ASCII文本。顺便说一句,你错过的另一个技巧是拨MemoryStreamToArray,这将给你的内容为byte[]没有额外的杂乱。

+0

我想我通过尝试转换为二进制代码而不是仅转换为字节数组增加了复杂性,但是我还没有碰到能够附加到我的问题的代码。 – JYelton 2010-08-11 22:09:48

+0

我已经更新了这个问题 - 我认为这与二进制转换一起工作,因为它以某种方式确保所有压缩字节都是ascii可打印的字符。如果我简单地将字符串转换为字节数组然后进行压缩,结果字节在可打印字符之外,因此我无法解码它。 – JYelton 2010-08-11 22:22:08

+0

@JYelton:在这种情况下,有一个更简单的答案。编辑... – 2010-08-11 22:25:46

0

如果您发布的数据代表所有的数据,那么你有一个换行符每4个字节,所以如果你转换回来的时候需要它,只要坚持一个在每4个字节的数据

+0

不幸的是它大大简化了,大多数行将是大约80个字节长,或40个2个字符的十六进制字符串。但它是可变的。 – JYelton 2010-08-11 22:08:53

+0

@JYelton太糟糕了,可变长度显然会让它更难:( – 2010-08-11 22:13:20

+0

如果是这种情况,它将会是蛋糕!如果长度是静态的,我会继续剥离换行符并在另一侧重新创建它们。 – JYelton 2010-08-11 22:14:37

相关问题