创建zip文件在.net与密码

vx6bjr1n  于 2023-03-24  发布在  .NET
关注(0)|答案(5)|浏览(247)

我在一个项目上工作,我需要在C#中创建具有密码保护的zip文件内容。
在我使用System.IO.Compression.GZipStream创建gzip内容之前。.net有任何创建zip或rar密码保护文件的功能吗?

ghhaqwfi

ghhaqwfi1#

看看DotNetZip(@AFract在评论中提供了一个新的GitHub链接)
它有相当geat文档,它还允许您在运行时加载dll作为嵌入文件。

oknrviil

oknrviil2#

不幸的是,框架中没有这样的功能。有一种方法可以制作ZIP文件,但没有密码。如果你想在C#中创建密码保护的ZIP文件,我推荐SevenZipSharp。它基本上是7-Zip的托管 Package 。

SevenZipBase.SetLibraryPath(Path.Combine(
        Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? Environment.CurrentDirectory,
        "7za.dll"));

SevenZipCompressor compressor = new SevenZipCompressor();

compressor.Compressing += Compressor_Compressing;
compressor.FileCompressionStarted += Compressor_FileCompressionStarted;
compressor.CompressionFinished += Compressor_CompressionFinished;

string password = @"whatever";
string destinationFile = @"C:\Temp\whatever.zip";
string[] sourceFiles = Directory.GetFiles(@"C:\Temp\YourFiles\");

if (String.IsNullOrWhiteSpace(password))
{
    compressor.CompressFiles(destinationFile, sourceFiles);
}
else
{
    //optional
    compressor.EncryptHeaders = true;
    compressor.CompressFilesEncrypted(destinationFile, password, sourceFiles);
}
kninwzqo

kninwzqo3#

DotNetZip以一种干净的方式工作得很好。

DotNetZip is a FAST, FREE class library and toolset for manipulating zip files.

代码

static void Main(string[] args)
{
        using (ZipFile zip = new ZipFile())
        {

            zip.Password = "mypassword";

            zip.AddDirectory(@"C:\Test\Report_CCLF5\");
            zip.Save(@"C:\Test\Report_CCLF5_PartB.zip");
        }
 }
ecfsfe2w

ecfsfe2w4#

我想增加更多的选择。
对于.NET可以使用SharpZipLib,对于Xamarin可以使用SharpZipLib.Portable
.NET示例:

using ICSharpCode.SharpZipLib.Zip;

// Compresses the supplied memory stream, naming it as zipEntryName, into a zip,
// which is returned as a memory stream or a byte array.
//
public MemoryStream CreateToMemoryStream(MemoryStream memStreamIn, string zipEntryName) {

    MemoryStream outputMemStream = new MemoryStream();
    ZipOutputStream zipStream = new ZipOutputStream(outputMemStream);

    zipStream.SetLevel(3); //0-9, 9 being the highest level of compression
    zipStream.Password = "Your password";

    ZipEntry newEntry = new ZipEntry(zipEntryName);
    newEntry.DateTime = DateTime.Now;

    zipStream.PutNextEntry(newEntry);

    StreamUtils.Copy(memStreamIn, zipStream, new byte[4096]);
    zipStream.CloseEntry();

    zipStream.IsStreamOwner = false;    // False stops the Close also Closing the underlying stream.
    zipStream.Close();          // Must finish the ZipOutputStream before using outputMemStream.

    outputMemStream.Position = 0;
    return outputMemStream;

    // Alternative outputs:
    // ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory.
    byte[] byteArrayOut = outputMemStream.ToArray();

    // GetBuffer returns a raw buffer raw and so you need to account for the true length yourself.
    byte[] byteArrayOut = outputMemStream.GetBuffer();
    long len = outputMemStream.Length;
}

更多示例可在here中找到。
如果您可以不使用密码功能,可以提到ZipStorerSystem.IO.Compression中内置的.NET功能。

0pizxfdo

0pizxfdo5#

我发现有两个选项是可靠的,并且很容易使用,这取决于允许您在项目中使用的许可证类型。
第一个是:

using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;

namespace DataReader.zip
{
internal static class Zip1 // SharpZipLib nuget lib, MIT free license
{
    public static bool Create(string destZipPath, string folderToCompress, string? password = null, int compressionLevel = 3)
    {
        bool res;

        try
        {
            var fsOut = File.Create($"{destZipPath}.zip"); // ending '.zip' is a must!
            var zipStream = new ZipOutputStream(fsOut);

            zipStream.SetLevel(compressionLevel); // 0-9, 9 being the highest level of compression

            zipStream.Password = password; // optional. Null is the same as not setting. Required if using AES.

            // This setting will strip the leading part of the folder path in the entries, to
            // make the entries relative to the starting folder.
            // To include the full path for each entry up to the drive root, assign folderOffset = 0.
            var folderOffset = folderToCompress.Length + (folderToCompress.EndsWith("\\") ? 0 : 1);

            res = CompressFolder(folderToCompress, zipStream, folderOffset);

            zipStream.IsStreamOwner = true; // Makes the Close also Close the underlying stream
            zipStream.Close();
            return res;
        }
        catch (Exception e)
        {
            return Console.WriteLine($"{e.Message}: {destZipPath}");
        }
    }

    private static bool CompressFolder(string path, ZipOutputStream zipStream, int folderOffset)
    {
        try
        {
            var files = Directory.GetFiles(path);

            if (files.Length == 0)
            {
                Message.Show($"Warning: no files to compress found in folder '{path}'");
                return false;
            }

            foreach (var filename in files)
            {
                var fi = new FileInfo(filename);
                var entryName = filename.Substring(folderOffset); // Makes the name in zip based on the folder
                entryName = ZipEntry.CleanName(entryName); // Removes drive from name and fixes slash direction
                var newEntry = new ZipEntry(entryName);
                newEntry.DateTime = fi.LastWriteTime; // Note the zip format stores 2 second granularity

                // Specifying the AESKeySize triggers AES encryption. Allowable values are 0 (off), 128 or 256.
                // A password on the ZipOutputStream is required if using AES.
                //  newEntry.AESKeySize = 256;

                // To permit the zip to be unpacked by built-in extractor in WinXP and Server2003, WinZip 8, Java, and other older code,
                // you need to do one of the following: Specify UseZip64.Off, or set the Size.
                // If the file may be bigger than 4GB, or you do not need WinXP built-in compatibility, you do not need either,
                // but the zip will be in Zip64 format which not all utilities can understand.
                   zipStream.UseZip64 = UseZip64.On;
                newEntry.Size = fi.Length;

                zipStream.PutNextEntry(newEntry);

                // Zip the file in buffered chunks
                // the "using" will close the stream even if an exception occurs
                var buffer = new byte[4096];
                using (var streamReader = File.OpenRead(filename))
                {
                    StreamUtils.Copy(streamReader, zipStream, buffer);
                }
                zipStream.CloseEntry();
            }
            return true;
        }
        catch (Exception e)
        {
            return Console.WriteLine($"{e.Message}: {destZipPath}");
        }
    }
}
}

第二个问题:

using Ionic.Zip;

namespace DataReader.zip
{
    internal class Zip2 // DotNetZip nuget lib
    {
        public static bool Create(string destZipPath, string folderToCompress, string? password = null, int compressionLevel = 3)
        {
            try
            {
                using ZipFile zip = new();

                if (password != null)
                    zip.Password = password;

                zip.CompressionLevel = (Ionic.Zlib.CompressionLevel)compressionLevel;
                zip.AddDirectory(folderToCompress);
                zip.Save($"{destZipPath}.zip");

                return true;
            }
            catch (Exception e)
            {
                return Console.WriteLine($"{e.Message}: {destZipPath}");
            }
        }
    }
}

使用这两个选项,您将创建一个zip文件夹,在其中需要密码才能提取文件(如果您在调用方法时设置了密码)。

相关问题