Как добавить существующий файл (image / mp4 / pdf) в ziparchive? -. Net Framework 4.6.2 - PullRequest
0 голосов
/ 29 января 2020

Я пытаюсь внедрить кнопку «Загрузить все», которая заархивирует выбранные файлы с сервера и вернет их при загрузке zip-файла. С кодом ниже, у меня есть файл zip создается. Ожидаемые файлы находятся внутри, с ожидаемыми именами файлов, но содержимое заархивированных файлов, похоже, повреждено.

public ActionResult DownloadAll(Guid id)
{
    var assets = db.InviteAssets.Include(i => i.AssetPages).Where(w => w.InviteID == id).ToList();

    var cd = new System.Net.Mime.ContentDisposition
    {
        // for example foo.bak
        FileName = "allAssets.zip",

        // always prompt the user for downloading, set to true if you want 
        // the browser to try to show the file inline
        Inline = false,
    };
    Response.AppendHeader("Content-Disposition", cd.ToString());

    using (var memoryStream = new MemoryStream())
    {
        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
        {
            foreach (var asset in assets)
            {
                string path, extension, name;
                if (asset.AssetType != AssetType.PDF)
                {
                    path = asset.AssetPages.First(f => f.PageNumber == 1).FilePath;
                }
                else
                {
                    path = string.Format("/Content/Assets/asset_{0}.pdf", asset.ID);
                }
                extension = path.Substring(path.IndexOf('.'));
                name = "asset" + asset.Order + extension;

                var file = archive.CreateEntry(name);

                using (var streamWriter = new StreamWriter(file.Open()))
                {
                    using (var fileStream = System.IO.File.Open(Server.MapPath("~" + path), FileMode.Open))
                    {
                        int filelength = (int)fileStream.Length;
                        var filedata = new byte[fileStream.Length];
                        streamWriter.Write(fileStream.Read(filedata, 0, filelength));
                    }
                }
            }
        }

        return File(memoryStream.ToArray(), "application/json", "allAssets.zip");
    }
}

Я думаю, что моя проблема связана с этим разделом:

using (var streamWriter = new StreamWriter(file.Open()))
{
    using (var fileStream = System.IO.File.Open(Server.MapPath("~" + path), FileMode.Open))
    {
        int filelength = (int)fileStream.Length;
        var filedata = new byte[fileStream.Length];
        streamWriter.Write(fileStream.Read(filedata, 0, filelength));
    }
}

Я продолжаю читать примеры, в которых используется метод archive.CreateEntryFromFile (filePath, fileName) , но такой метод не распознается. Это устарело или требуется более высокая версия. Net Framework?

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 29 января 2020

Проблема здесь:

streamWriter.Write(fileStream.Read(filedata, 0, filelength));

Вы читаете содержимое файла в filedata, но в то же время вы записываете возвращаемое значение Read в архив, что означает один инт. Вам нужно читать и писать отдельно:

fileStream.Read(filedata, 0, filelength));
streamWriter.Write(filedata, 0, filelength);

Или вы можете использовать метод расширения CreateEntryFromFile в System.IO.Compression.ZipFileExtensions пространстве имен.

0 голосов
/ 29 января 2020

Я обнаружил, что причина, по которой я не вижу метод CreateEntryFromFile , заключается в том, что я не включил ссылку на System.IO.Compression.FileSystem . Как только я добавил это, я мог использовать CreateEntryFromFile , который работал нормально.

Так что теперь у меня есть: archive.CreateEntryFromFile(Server.MapPath("~" + path), name);

Вместо:

var file = archive.CreateEntry(name);

using (var streamWriter = new StreamWriter(file.Open()))
{
    using (var fileStream = System.IO.File.Open(Server.MapPath("~" + path), FileMode.Open))
    {
        int filelength = (int)fileStream.Length;
        var filedata = new byte[fileStream.Length];
        fileStream.Read(filedata, 0, filelength);
        streamWriter.Write(filedata);
    }
}
...