解压缩C#中的数据
本文关键字:数据 解压缩 | 更新日期: 2023-09-27 18:25:37
我是C#的新手,我正在编写一个简单的web服务。它获取zip文件并在文件系统中对其进行解压缩。C#中的代码是:
[WebMethod]
public String SetZip(string device_id, string file)
{
if (device_id == null || device_id.Length == 0)
{
return "10;no auth data";
}
StringBuilder output = new StringBuilder();
if (direcory == null)
{
return output.ToString();
}
string dirname = "c:''temp''" + direcory + "''";
if (!System.IO.Directory.Exists(dirname))
{
System.IO.Directory.CreateDirectory(dirname);
}
string filename = dirname + "file1.txt";
string text = UnZipStr(Convert.FromBase64String(file));
File.WriteAllText(filename, text);
output.AppendLine("0;done");
return output.ToString();
}
public static string UnZipStr(byte[] input)
{
using (MemoryStream memstream = new MemoryStream())
{
using (MemoryStream inputStream = new MemoryStream(input))
{
using (DeflateStream gzip =
new DeflateStream(inputStream, CompressionMode.Decompress))
{
using (StreamReader reader =
new StreamReader(gzip, System.Text.Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
}
}
并从java代码发送zip数据:
void callService(byte[] xmlData) {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("device_id", AGENT);
Deflater deflater = new Deflater();
deflater.setInput(xmlData);
deflater.finish();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
while (!deflater.finished()) {
int byteCount = deflater.deflate(buf);
baos.write(buf, 0, byteCount);
}
deflater.end();
byte[] compressedBytes = baos.toByteArray();
request.addPropertyIfValue("file", org.kobjects.base64.Base64.encode(compressedBytes));...}
在C#代码中,从StreamReader 读取数据时出现异常
SoapFault - faultcode: 'soap:Server' faultstring: 'System.Web.Services.Protocols.SoapException: ---> InvalidDataException: Block length does not correspond to the complement.
System.IO.Compression.Inflater.DecodeUncompressedBlock(Boolean& end_of_block)
System.IO.Compression.Inflater.Decode()
System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length)
System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count)
System.IO.StreamReader.ReadBuffer()
System.IO.StreamReader.ReadToEnd()
Service.UnZipStr(Byte[] input) в c:'inetpub'wwwroot'WebSite'App_Code'Service.cs: at 94
Service.SetZip(String device_id, String file) в c:'inetpub'wwwroot'WebSite'App_Code 'Service.cs: at 73
我做错了什么?
编辑:我一直在研究,有一种方法可以从C#识别的Java生成DEFLATE格式的数据:您必须使用Deflater(int,boolean)
构造函数。因此,将您的Java代码更改为:
Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
deflater.setInput(xmlData);
deflater.finish();
原因是默认情况下,deflater会发出一个ZLIB标头和校验和,而C#DeflateStream
没有预料到这一点。
Java和C#似乎在"deflate"压缩算法的确切种类上并不一致,但根据我的测试,"gzip"应该可以工作:
这在Java:中压缩xmlData
ByteArrayOutputStream baos = new ByteArrayOutputStream()
OutputStream out = new GZIPOutputStream(baos);
out.write(xmlData);
out.close();
byte[] compressedBytes = baos.toByteArray();
此解压缩C#中的input
:
using (MemoryStream inputStream = new MemoryStream(input))
{
using (GZipStream gzip = new GZipStream(inputStream, CompressionMode.Decompress))
{
using (StreamReader reader = new StreamReader(gzip, System.Text.Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
@Joni Salonen似乎已经给出了放气问题的答案,所以我想添加一些关于架构的内容。为了隔离问题,您应该将这两个关注点分开。首先,您需要删除一个压缩文件。然后你需要缩小它。然后,分别关注问题领域。你可以随时"管道"这两个关注点以后。
顺便说一句,在许多情况下,拥有原始zip文件是很有用的。当某些事情没有按计划进行时,尤其是当你只有一次机会捕获文件时,它就会成为一个安全网。