在 C# 中解压 .gz 流
Decompress .gz Stream in C#
对不起,如果这是一个菜鸟问题,这是我第一次使用 C#。
此代码的目的是检索一个 .gz 文件,将其解压缩并将内容推送到一个字符串中,然后我可以使用它来编组内部的 XML。
从服务器请求特定的 .gz 文件后,我将结果发送到流中,如下所示:
HttpWebResponse OauthResponse = (HttpWebResponse)OauthRequest.GetResponse();
Stream stream = OauthResponse.GetResponseStream();
但是,我找不到任何关于如何解压 Stream 中的 .gz 的答案,只能找到如何从文件中解压的答案。所以我使用这个将传入的 .gz 保存到本地文件中:
using (StreamReader sr = new StreamReader(stream))
{
using (BinaryWriter writer = new BinaryWriter(File.Open("currentSession.gz", FileMode.Create)))
{
writer.Write(sr.ReadToEnd());
}
}
然后尝试解压缩新创建的文件:
using (GZipStream instream = new GZipStream(File.OpenRead("currentSession.gz"), CompressionMode.Decompress))
{
using (FileStream outputStream = new FileStream("currentXML.xml", FileMode.Append, FileAccess.Write))
{
int bufferSize = 8192, bytesRead = 0;
byte[] buffer = new byte[bufferSize];
while ((bytesRead = instream.Read(buffer, 0, bufferSize)) > 0)
{
outputStream.Write(buffer, 0, bytesRead);
}
}
}
目的是创建一个 XML 文件,然后可以调用该文件将节点编组到一个对象中。但是,当我 运行 它时,我得到:
'System.IO.InvalidDataException' 类型的未处理异常发生在 System.dll
Additional information: The magic number in GZip header is not
correct. Make sure you are passing in a GZip stream.
我的问题是我是否遵循了正确的过程,即在 Stream 中获取 .gz 文件,保存它,调用新保存的 .gz 文件解压缩并保存到 XML 文件, 调用新的 .xml 然后编组它。如果是,我在这里做错了什么。如果没有,有没有办法在 gz 中获取 XML 而无需创建和加载新文件?
抛出此异常是因为您尝试使用 GZipStream 解压缩的 Stream 不是有效的 GZip,您可以使用此代码重现此异常:
Stream stream = new MemoryStream(Encoding.UTF8.GetBytes("Hellow"));
try
{
using (var instream = new GZipStream(stream, CompressionMode.Decompress))
using (var outputStream = new FileStream("currentXML.xml", FileMode.Append, FileAccess.Write))
{
instream.CopyTo(outputStream);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
输出
The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.
所以您必须确保您正在从 WebRequest 接收 GZIP 流,
你也可以简化你的代码,像这样:
HttpWebResponse OauthResponse = (HttpWebResponse)OauthRequest.GetResponse();
Stream stream = OauthResponse.GetResponseStream();
using (var instream = new GZipStream(stream, CompressionMode.Decompress))
using (var outputStream = new FileStream("currentXML.xml", FileMode.Append, FileAccess.Write))
instream.CopyTo(outputStream);
最后,我设法通过将 .gz 流保存到文件中,然后读取这些文件以解压缩 xml,然后保存 xml 文件来使其工作。再往下,当数据已经编组后,剔除文件,避免浪费space.
public static void saveDecompress(Stream LPDataStream, int c)
{
//Save the incoming .gz in a file
using (FileStream output = File.OpenWrite("temp/session" + c + ".gz"))
{
LPDataStream.CopyTo(output);
}
DirectoryInfo directorySelected = new DirectoryInfo("temp/");
//Iterate through the .gz files to extract xml
foreach (FileInfo fileToDecompress in directorySelected.GetFiles("*.gz"))
{
using (FileStream originalFileStream = fileToDecompress.OpenRead())
{
string currentFileName = fileToDecompress.FullName;
string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length) + ".xml";
//Save XML in file
using (FileStream decompressedFileStream = File.Create(newFileName))
{
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
}
}
}
}
}
我希望这对其他人有帮助。
对不起,如果这是一个菜鸟问题,这是我第一次使用 C#。
此代码的目的是检索一个 .gz 文件,将其解压缩并将内容推送到一个字符串中,然后我可以使用它来编组内部的 XML。
从服务器请求特定的 .gz 文件后,我将结果发送到流中,如下所示:
HttpWebResponse OauthResponse = (HttpWebResponse)OauthRequest.GetResponse();
Stream stream = OauthResponse.GetResponseStream();
但是,我找不到任何关于如何解压 Stream 中的 .gz 的答案,只能找到如何从文件中解压的答案。所以我使用这个将传入的 .gz 保存到本地文件中:
using (StreamReader sr = new StreamReader(stream))
{
using (BinaryWriter writer = new BinaryWriter(File.Open("currentSession.gz", FileMode.Create)))
{
writer.Write(sr.ReadToEnd());
}
}
然后尝试解压缩新创建的文件:
using (GZipStream instream = new GZipStream(File.OpenRead("currentSession.gz"), CompressionMode.Decompress))
{
using (FileStream outputStream = new FileStream("currentXML.xml", FileMode.Append, FileAccess.Write))
{
int bufferSize = 8192, bytesRead = 0;
byte[] buffer = new byte[bufferSize];
while ((bytesRead = instream.Read(buffer, 0, bufferSize)) > 0)
{
outputStream.Write(buffer, 0, bytesRead);
}
}
}
目的是创建一个 XML 文件,然后可以调用该文件将节点编组到一个对象中。但是,当我 运行 它时,我得到:
'System.IO.InvalidDataException' 类型的未处理异常发生在 System.dll
Additional information: The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.
我的问题是我是否遵循了正确的过程,即在 Stream 中获取 .gz 文件,保存它,调用新保存的 .gz 文件解压缩并保存到 XML 文件, 调用新的 .xml 然后编组它。如果是,我在这里做错了什么。如果没有,有没有办法在 gz 中获取 XML 而无需创建和加载新文件?
抛出此异常是因为您尝试使用 GZipStream 解压缩的 Stream 不是有效的 GZip,您可以使用此代码重现此异常:
Stream stream = new MemoryStream(Encoding.UTF8.GetBytes("Hellow"));
try
{
using (var instream = new GZipStream(stream, CompressionMode.Decompress))
using (var outputStream = new FileStream("currentXML.xml", FileMode.Append, FileAccess.Write))
{
instream.CopyTo(outputStream);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
输出
The magic number in GZip header is not correct. Make sure you are passing in a GZip stream.
所以您必须确保您正在从 WebRequest 接收 GZIP 流,
你也可以简化你的代码,像这样:
HttpWebResponse OauthResponse = (HttpWebResponse)OauthRequest.GetResponse();
Stream stream = OauthResponse.GetResponseStream();
using (var instream = new GZipStream(stream, CompressionMode.Decompress))
using (var outputStream = new FileStream("currentXML.xml", FileMode.Append, FileAccess.Write))
instream.CopyTo(outputStream);
最后,我设法通过将 .gz 流保存到文件中,然后读取这些文件以解压缩 xml,然后保存 xml 文件来使其工作。再往下,当数据已经编组后,剔除文件,避免浪费space.
public static void saveDecompress(Stream LPDataStream, int c)
{
//Save the incoming .gz in a file
using (FileStream output = File.OpenWrite("temp/session" + c + ".gz"))
{
LPDataStream.CopyTo(output);
}
DirectoryInfo directorySelected = new DirectoryInfo("temp/");
//Iterate through the .gz files to extract xml
foreach (FileInfo fileToDecompress in directorySelected.GetFiles("*.gz"))
{
using (FileStream originalFileStream = fileToDecompress.OpenRead())
{
string currentFileName = fileToDecompress.FullName;
string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length) + ".xml";
//Save XML in file
using (FileStream decompressedFileStream = File.Create(newFileName))
{
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
}
}
}
}
}
我希望这对其他人有帮助。