从字节(在内存中使用任意编码的文本)在内存中创建zip文件 [英] Create zip file in memory from bytes (text with arbitrary encoding)

查看:75
本文介绍了从字节(在内存中使用任意编码的文本)在内存中创建zip文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发的应用程序需要将xml文件压缩为zip文件,然后通过http请求将其发送到网络服务。由于我不需要保留zip文件,因此我只是在内存中执行压缩。该Web服务拒绝我的请求,因为zip文件显然格式错误。

The application i'm developing needs to compress xml files into zip files and send them through http requests to a web service. As I dont need to keep the zip files, i'm just performing the compression in memory. The web service is denying my requests because the zip files are apparently malformed.

我知道此问题,效果很好,但它使用了 StreamWriter 。我对该解决方案的问题是 StreamWriter 需要编码或采用 UTF-8 ,而我不需要知道xml文件的编码。我只需要从这些文件中读取字节,并将它们存储在zip文件中,无论它们使用哪种编码即可。

I know there is a solution in this question which works perfectly, but it uses a StreamWriter. My problem with that solution is that StreamWriter requires an encoding or assumes UTF-8, and I do not need to know the enconding of the xml files. I just need to read the bytes from those files, and store them inside a zip file, whatever encoding they use.

因此,很明显,这个问题没有什么要解决的。使用编码,因为我不需要将字节转换为文本或相反。我只需要压缩一个 byte []

So, to be clear, this question has nothing to do with encodings, as I don't need to transform the bytes into text or the oposite. I just need to compress a byte[].

我正在使用下一个代码来测试我的zip压缩方式文件格式不正确:

I'm using the next code to test how my zip file is malformed:

static void Main(string[] args)
{
    Encoding encoding = Encoding.GetEncoding("ISO-8859-1");

    string xmlDeclaration = "<?xml version=\"1.0\" encoding=\"" + encoding.WebName.ToUpperInvariant() + "\"?>";
    string xmlBody = "<Test>ª!\"·$%/()=?¿\\|@#~€¬'¡º</Test>";
    string xmlContent = xmlDeclaration + xmlBody;
    byte[] bytes = encoding.GetBytes(xmlContent);
    string fileName = "test.xml";
    string zipPath = @"C:\Users\dgarcia\test.zip";

    Test(bytes, fileName, zipPath);
}

static void Test(byte[] bytes, string fileName, string zipPath)
{
    byte[] zipBytes;

    using (var memoryStream = new MemoryStream())
    using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: false))
    {
        var zipEntry = zipArchive.CreateEntry(fileName);
        using (Stream entryStream = zipEntry.Open())
        {
            entryStream.Write(bytes, 0, bytes.Length);
        }

        //Edit: as the accepted answer states, the problem is here, because i'm reading from the memoryStream before disposing the zipArchive.
        zipBytes = memoryStream.ToArray();
    }

    using (var fileStream = new FileStream(zipPath, FileMode.OpenOrCreate))
    {
        fileStream.Write(zipBytes, 0, zipBytes.Length);
    }
}

如果我尝试打开该文件,则会看到一个文件意外结束错误。因此,显然,Web服务正在正确报告格式错误的zip文件。到目前为止,我已经尝试过:

If I try to open that file, I get an "Unexpected end of file" error. So apparently, the web service is correctly reporting a malformed zip file. What I have tried so far:


  • 刷新 entryStream

  • 关闭 entryStream

  • 刷新并关闭 entryStream

  • Flushing the entryStream.
  • Closing the entryStream.
  • Both flushing and closing the entryStream.

请注意,如果我直接从以下位置打开 zipArchive zip文件 fileStream 的形成没有错误。但是, fileStream 只是作为测试,我需要在内存中创建我的zip文件。

Note that if I open the zipArchive directly from the fileStream the zip file is formed with no errors. However, the fileStream is just there as a test, and I need to create my zip file in memory.

推荐答案

您试图过早从 MemoryStream 获取字节, ZipArchive 却没有全部写下来。而是这样做:

You are trying to get bytes from MemoryStream too early, ZipArchive did not write them all yet. Instead, do like this:

using (var memoryStream = new MemoryStream()) {
    // note "leaveOpen" true, to not dispose memoryStream too early
    using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, leaveOpen: true)) {
        var zipEntry = zipArchive.CreateEntry(fileName);
        using (Stream entryStream = zipEntry.Open()) {
            entryStream.Write(bytes, 0, bytes.Length);
        }                    
    }
    // now, after zipArchive is disposed - all is written to memory stream
    zipBytes = memoryStream.ToArray();
}

这篇关于从字节(在内存中使用任意编码的文本)在内存中创建zip文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆