如何在内存中创建zip文件?

3

我需要从一组网址创建一个zip文件,并且它应该有适当的文件夹结构。因此,我尝试了如下:

   public async Task<byte[]> CreateZip(Guid ownerId)
    {
        try
        {
            string startPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "zipFolder");//base folder
            if (Directory.Exists(startPath))
            {
                DeleteAllFiles(startPath);
                Directory.Delete(startPath);
            }
            Directory.CreateDirectory(startPath);

            string zipPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{ownerId.ToString()}"); //folder based on ownerid
            if (Directory.Exists(zipPath))
            {
                DeleteAllFiles(zipPath);
                Directory.Delete(zipPath);
            }

            Directory.CreateDirectory(zipPath);
            var attachemnts = await ReadByOwnerId(ownerId);

            attachemnts.Data.ForEach(i =>
            {
                var fileLocalPath = $"{startPath}\\{i.Category}";
                if (!Directory.Exists(fileLocalPath))
                {
                    Directory.CreateDirectory(fileLocalPath);
                }
                using (var client = new WebClient())
                {
                    client.DownloadFile(i.Url, $"{fileLocalPath}//{i.Flags ?? ""}_{i.FileName}");
                }
            });
            var zipFilename = $"{zipPath}//result.zip";

            if (File.Exists(zipFilename))
            {
                File.Delete(zipFilename);
            }

            ZipFile.CreateFromDirectory(startPath, zipFilename, CompressionLevel.Fastest, true);


            var result = System.IO.File.ReadAllBytes(zipFilename);
            return result;
        }
        catch (Exception ex)
        {
            var a = ex;
            return null;
        }
    }

目前我将所有文件都写在我的基础目录中(可能不是一个好主意)。目前,我必须手动删除所有文件夹和文件以避免异常/不需要的文件。是否可以将所有内容都写入内存中?

如果要将所有文件和文件夹结构都写入内存中,需要做哪些更改呢?


我想从URL创建一个源文件/文件夹结构,并且我也希望它在内存中。您可以查看我的foreach循环以创建文件夹。 - hilda_sonica_vish
我不知道如何在内存中创建文件夹结构。根据您的部署环境,您可以在服务器上创建一个临时工作文件夹,该文件夹不在应用程序文件夹中。我们经常使用这样的东西。 - Peter Smith
正如@PeterSmith所说,我会创建一个临时工作文件夹。例如一个新的Guid,类似于: "/xxxx-xxxx-xxxx-xxxx/Folder-To-Zip/...." - Kiksen
你可以使用这个问题的答案。但是你必须在调用zipArchive.CreateEntry时,在文件名前面加上目录名称,比如zipArchive.CreateEntry($"{startPath}\\{attachment.FileName}" - oleksa
如何在压缩文件中保持文件夹结构? - hilda_sonica_vish
显示剩余2条评论
2个回答

1

不,你不能。至少用内置的Dotnet是不行的。

enter image description here

根据我的评论,我建议将文件存储在基于Guid或类似的自定义位置中。例如:" /xxxx-xxxx-xxxx-xxxx/Folder-To-Zip/...."。这样可以确保您可以处理多个请求,其中包含相同的文件或类似的文件/文件夹名称。然后,您只需要在之后清理和删除文件夹,以便不会耗尽空间。

0
希望下面的代码能够完成工作。
public async Task<byte[]> CreateZip(Guid ownerId)
        {
            try
            {
                string startPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}_zipFolder");//folder to add

                Directory.CreateDirectory(startPath);

                var attachemnts = await ReadByOwnerId(ownerId);
                attachemnts.Data = filterDuplicateAttachments(attachemnts.Data);
                //filtering youtube urls
                attachemnts.Data = attachemnts.Data.Where(i => !i.Flags.Equals("YoutubeUrl", StringComparison.OrdinalIgnoreCase)).ToList();

                attachemnts.Data.ForEach(i =>
                {
                    var fileLocalPath = $"{startPath}\\{i.Category}";
                    if (!Directory.Exists(fileLocalPath))
                    {
                        Directory.CreateDirectory(fileLocalPath);
                    }
                    using (var client = new WebClient())
                    {
                        client.DownloadFile(i.Url, $"{fileLocalPath}//{i.Flags ?? ""}_{i.FileName}");
                    }
                });

                using (var ms = new MemoryStream())
                {
                    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
                    {
                        System.IO.DirectoryInfo di = new DirectoryInfo(startPath);
                        var allFiles = di.GetFiles("",SearchOption.AllDirectories);
                        foreach (var attachment in allFiles)
                        {
                            var file = File.OpenRead(attachment.FullName);

                            var type = attachemnts.Data.Where(i => $"{ i.Flags ?? ""}_{ i.FileName}".Equals(attachment.Name, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                            var entry = zipArchive.CreateEntry($"{type.Category}/{attachment.Name}", CompressionLevel.Fastest);
                            using (var entryStream = entry.Open())
                            {
                                file.CopyTo(entryStream);
                            }
                        }
                    }
                    var result = ms.ToArray();
                    return result;
                }
            }
            catch (Exception ex)
            {
                var a = ex;
                return null;
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接