C# 解压流
我试图使用GZipStream和BinaryStream对流进行解压缩,但失败了 你能帮我吗C# 解压流,c#,stream,gzipstream,compression,C#,Stream,Gzipstream,Compression,我试图使用GZipStream和BinaryStream对流进行解压缩,但失败了 你能帮我吗 public static LicenseOwnerRoot GetLicenseFromStream(Stream stream) { using (BinaryReader br = new BinaryReader(stream)) { string keyCrypto = br.ReadString();
public static LicenseOwnerRoot GetLicenseFromStream(Stream stream)
{
using (BinaryReader br = new BinaryReader(stream))
{
string keyCrypto = br.ReadString();
string xmlCrypto = br.ReadString();
string key = Cryptography.Decrypt(keyCrypto);
string xml = Cryptography.Decrypt(key, xmlCrypto);
byte[] data = Encoding.UTF8.GetBytes(xml.ToCharArray());
using (MemoryStream ms = new MemoryStream(data))
{
using (GZipStream decompress = new GZipStream(ms, CompressionMode.Decompress))
{
xml = Encoding.UTF8.GetString(data);
LicenseOwnerRoot root = (LicenseOwnerRoot)Utility.XmlDeserialization(typeof(LicenseOwnerRoot), xml);
foreach (LicenseOwnerItem loi in root.Licenses)
loi.Root = root;
return root;
}
}
}
}
xml是经过压缩和加密的,所以我必须先解压缩,然后解密。当我尝试阅读时,抛出一个预期消息:GZip头中的幻数不正确。我试了很多次来解决这个问题,但听起来是可行的。
问题是:我应该如何使用“usings”,以及这种方式是否正确,或者是否存在另一种方式来完成我试图做的事情?
在使用BinaryReader之前,我必须先解压缩
实际上,我必须做这个方法的相反:
public static void GenerateLicenseStream(string key, LicenseOwnerRoot root, Stream stream)
{
using (BinaryWriter sw = new BinaryWriter(stream))
{
string xml = Utility.XmlSerialization(root);
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream compress = new GZipStream(ms, CompressionMode.Compress))
{
byte[] data = Encoding.UTF8.GetBytes(xml.ToCharArray());
compress.Write(data, 0, data.Length);
string keyCrypto = Cryptography.Encrypt(key);
string xmlCrypto = Cryptography.Encrypt(key, Encoding.UTF8.GetString(ms.ToArray()));
sw.Write(keyCrypto);
sw.Write(xmlCrypto);
}
}
}
}
您将压缩数据视为utf-8字节数组。Utf-8实际上有非常严格的规则,所以在这一步中,压缩数据的一半可能会被问号(无效字符的占位符)取代 您需要加密/解密原始二进制数据,并丢失字符串转换。压缩数据不是字符串,不应被视为字符串 如果您的加密方法只能对字符串进行操作(我没有
加密
类的定义),那么您别无选择,只能先对XML数据进行加密,然后对其进行压缩(尽管这样可能不会压缩)
你实际上也没有做任何减压;您为压缩的数据构造了一个
MemoryStream
和GZipStream
,但不使用它们,而是尝试直接使用数据。您没有从“解压缩”中读取任何内容。您需要从“解压”中读取所有数据(因为在流为空之前,您无需读取存储的数据长度),然后在执行操作时将其转换为字符串。我为您编写了一个快速示例,它不进行加密,但它突出显示了应该进行加密/解密的位置。这是可以“按原样”运行的.NET控制台应用程序的内容:
static void Main(字符串[]args)
{
var content=@“sometextorxmlcontentgoeserecanbeany#$&%&*(@#$^”;
var data=Encoding.UTF8.GetBytes(content.tocharray());
var fs=newstreamwriter(@“c:\users\stackoverflow\desktop\sample.bin”);
使用(var bw=newbinarywriter(fs.BaseStream))
{
使用(var ms=new MemoryStream())
{
使用(var compress=new GZipStream(ms,CompressionMode.compress,true))
{
压缩.写入(数据,0,数据.长度);
}
//加密在这里
var compressedData=ms.ToArray();
Console.WriteLine(compressedData.Length);/179
写入(压缩数据);
}
}
//而反过来。。。
使用(var fs2=newstreamreader(@“c:\users\stackoverflow\desktop\sample.bin”))
{
使用(var br=新二进制读取器(fs2.BaseStream))
{
var len=(int)br.BaseStream.Length;
var encrypted=br.ReadBytes(len);
//在这里解密
var decrypted=加密;//-1)
{
bytesList.Add((字节)val);
val=decompress.ReadByte();
}
}
var final_result=新字符串(Encoding.UTF8.GetChars(bytesList.ToArray());
控制台写入线(最终结果);
}
}
}
Console.ReadLine();
}
static void Main(string[] args)
{
var content = @"someTextOrXMLContentGoesHereCanBeAnything#$&%&*(@#$^";
var data = Encoding.UTF8.GetBytes(content.ToCharArray());
var fs = new StreamWriter(@"c:\users\stackoverflow\desktop\sample.bin");
using (var bw = new BinaryWriter(fs.BaseStream))
{
using (var ms = new MemoryStream())
{
using (var compress = new GZipStream(ms, CompressionMode.Compress, true))
{
compress.Write(data, 0, data.Length);
}
// encrypt goes here
var compressedData = ms.ToArray();
Console.WriteLine(compressedData.Length); // 179
bw.Write(compressedData);
}
}
// and the reverse...
using (var fs2 = new StreamReader(@"c:\users\stackoverflow\desktop\sample.bin"))
{
using (var br = new BinaryReader(fs2.BaseStream))
{
var len = (int)br.BaseStream.Length;
var encrypted = br.ReadBytes(len);
// decrypt here
var decrypted = encrypted; // <== new result after decryption
using (var ms = new MemoryStream(decrypted))
{
List<byte> bytesList = new List<byte>();
using (var decompress = new GZipStream(ms, CompressionMode.Decompress, true))
{
int val = decompress.ReadByte();
while (val > -1)
{
bytesList.Add((byte)val);
val = decompress.ReadByte();
}
}
var final_result = new String(Encoding.UTF8.GetChars(bytesList.ToArray()));
Console.WriteLine(final_result);
}
}
}
Console.ReadLine();
}