Làm cách nào để tạo kho lưu trữ 7-Zip với .NET?


101

Làm cách nào để tạo tệp lưu trữ 7-Zip từ ứng dụng bảng điều khiển C # của tôi? Tôi cần có thể giải nén các kho lưu trữ bằng chương trình 7-Zip thông thường, phổ biến rộng rãi .


Đây là kết quả của tôi với các ví dụ được cung cấp làm câu trả lời cho câu hỏi này

  • "Tách" thành 7z.exe - đây là cách tiếp cận đơn giản và hiệu quả nhất, và tôi có thể xác nhận rằng nó hoạt động tốt . Như workmad3 đã đề cập , tôi chỉ cần đảm bảo rằng 7z.exe được cài đặt trên tất cả các máy mục tiêu, đó là điều tôi có thể đảm bảo.
  • 7Zip trong nén bộ nhớ - điều này đề cập đến việc nén cookie "trong bộ nhớ" trước khi gửi đến máy khách; phương pháp này có vẻ hơi hứa hẹn. Kiểu trả về của phương thức trình bao bọc (gói LZMA SDK ) byte[]. Khi tôi ghi byte[]mảng vào một tệp, tôi không thể giải nén nó bằng 7-Zip ( File.7z is not supported archive).
  • 7zSharp Wrapper (được tìm thấy trên CodePlex) - cái này bao bọc SDK 7z exe / LZMA . Tôi đã tham chiếu dự án từ ứng dụng của mình và nó đã tạo thành công một số tệp lưu trữ, nhưng tôi không thể giải nén các tệp bằng chương trình 7-Zip thông thường ( File.7z is not supported archive).
  • 7Zip SDK hay còn gọi là LZMA SDK - Tôi đoán mình không đủ thông minh để tìm ra cách sử dụng cái này (đó là lý do tại sao tôi đăng ở đây) ... Bất kỳ ví dụ mã hoạt động nào chứng minh việc tạo một kho lưu trữ 7zip có thể được trích xuất bởi chương trình 7zip thông thường?
  • Giao diện CodeProject C # (.NET) cho 7-Zip Archive DLL - chỉ hỗ trợ giải nén từ các kho lưu trữ 7zip ... Tôi cần tạo chúng!
  • SharpZipLib - Theo Câu hỏi thường gặp của họ , SharpZipLib không hỗ trợ 7zip.

32
Đừng viết nó từ Google khi tất cả liên kết là từ bài viết của tôi dưới đây. Không tôn trọng lắm những người đã dành thời gian tìm kiếm cho bạn một số giải pháp.
Patrick Desjardins 22/10/08

3
Tôi biết bài đăng này đã cũ, nhưng tôi đã thấy một dự án tên là SevenZipSharp trong nghiên cứu của tôi hôm nay. Sevenzipsharp.codeplex.com
Timmerz

12
Chỉ là một lời cảnh báo cho độc giả trong tương lai. SevenZipSharp dường như là một phần mềm bỏ rơi. Cho đến hôm nay, bản phát hành ổn định mới nhất (0,64) đã được phát hành vào tháng 8 năm 2010 với một số vấn đề đa luồng khó chịu (theo các báo cáo lỗi). Chỉ có một số cam kết mã nguồn đã được đăng kể từ đó.
Anttu

Câu trả lời:


28

Nếu bạn có thể đảm bảo ứng dụng 7-zip sẽ được cài đặt (và trong đường dẫn) trên tất cả các máy mục tiêu, bạn có thể giảm tải bằng cách gọi ứng dụng dòng lệnh 7z. Không phải là giải pháp thanh lịch nhất nhưng nó là công việc ít nhất.


7
Chúng tôi thực sự gửi tiện ích dòng lệnh 7z với các mã nhị phân của chúng tôi và bao gồm nó. Hoạt động thực sự tốt cho chúng tôi.
David Mohundro 22/10/08

79

Ví dụ về cookie EggCafe 7Zip Đây là một ví dụ (cookie nén) với DLL của 7Zip.

CodePlex Wrapper Đây là một dự án mã nguồn mở có chức năng nén dọc của 7z.

7Zip SDK SDK chính thức cho 7zip (C, C ++, C #, Java) <--- Đề xuất của tôi

Thư viện zip .Net của SharpDevelop.net

Ví dụ về CodeProject với 7zip

SharpZipLib Nhiều nén


Xong và tôi cũng đã thêm một dự án mã nguồn mở hữu ích.
Patrick Desjardins 21/10/08

1
CƯỜI LỚN? Thay đổi cookie bằng một chuỗi ... một tệp hay bất cứ thứ gì ... lol?
Patrick Desjardins 21/10/08

1
Không, tôi chỉ muốn xem liệu có ai đã đưa ra một ví dụ làm việc ... Cảm ơn bạn đã nghiên cứu, nhưng không có liên kết nào bạn cung cấp có thể dẫn tôi đến điều gì đó hiệu quả.
Seibar 22/10/08

2
Tôi phải đồng ý rằng không có mã nào có mã mà bạn có thể sao chép và dán. SDK là cái có tất cả câu trả lời, nhưng cần một chút thời gian và nỗ lực để có một cái gì đó hoạt động. Tôi có thể hiểu bạn không muốn làm điều đó. Chúc một ngày tốt lành.
Patrick Desjardins 22/10/08

3
Dù sao, tôi khuyên bạn nên xóa các tham chiếu SharpDevelop / SharpZipLib, vì cả hai đều tham chiếu giống nhau và chúng không hỗ trợ 7-Zip. Seibar yêu cầu rõ ràng cho 7z. Tôi cũng đang tìm kiếm các giải pháp 7z vì ShaprZipLib không hoạt động với kho lưu trữ và tìm thấy chủ đề này. ShaprZipLib là một gợi ý gây hiểu lầm!
Onsokumaru

25

SevenZipSharp là một giải pháp khác. Tạo kho lưu trữ 7-zip ...


7
Bài đăng này của markhor thực sự là từ người tạo ra dự án SevenZipSharp. SevenZipSharp cho phép truy cập có lập trình vào dll 7Zip, làm cho nó rất đầy đủ tính năng. Tôi nhận thấy LZMA SDK ở mức thấp và khó hiểu. Ngược lại, SevenZipSharp được ghi chép đầy đủ, dễ sử dụng và có nhiều cách sử dụng mẫu trong dự án thử nghiệm của nó. Sử dụng các ví dụ, tôi có thể nhanh chóng nén và giải nén bằng cách sử dụng tệp hoặc bộ nhớ.
John Wigger

4
SevenZipSharp dường như bị bỏ rơi. Xem bình luận trước đây của tôi trong câu hỏi.
Anttu

SevenZipSharp chậm. Hiện tại, giải pháp được khuyến nghị nhất là sử dụng Process.Start ("7z.exe ......)
klm_

24

Đây là một ví dụ hoạt động hoàn chỉnh bằng cách sử dụng SevenZip SDK trong C #.

Nó sẽ ghi và đọc các tệp 7zip chuẩn như được tạo bởi ứng dụng Windows 7zip.

Tái bút. Ví dụ trước đó sẽ không bao giờ được giải nén vì nó không bao giờ ghi thông tin thuộc tính bắt buộc vào đầu tệp.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SevenZip.Compression.LZMA;
using System.IO;
using SevenZip;

namespace VHD_Director
{
    class My7Zip
    {
        public static void CompressFileLZMA(string inFile, string outFile)
        {
            Int32 dictionary = 1 << 23;
            Int32 posStateBits = 2;
            Int32 litContextBits = 3; // for normal files
            // UInt32 litContextBits = 0; // for 32-bit data
            Int32 litPosBits = 0;
            // UInt32 litPosBits = 2; // for 32-bit data
            Int32 algorithm = 2;
            Int32 numFastBytes = 128;

            string mf = "bt4";
            bool eos = true;
            bool stdInMode = false;


            CoderPropID[] propIDs =  {
                CoderPropID.DictionarySize,
                CoderPropID.PosStateBits,
                CoderPropID.LitContextBits,
                CoderPropID.LitPosBits,
                CoderPropID.Algorithm,
                CoderPropID.NumFastBytes,
                CoderPropID.MatchFinder,
                CoderPropID.EndMarker
            };

            object[] properties = {
                (Int32)(dictionary),
                (Int32)(posStateBits),
                (Int32)(litContextBits),
                (Int32)(litPosBits),
                (Int32)(algorithm),
                (Int32)(numFastBytes),
                mf,
                eos
            };

            using (FileStream inStream = new FileStream(inFile, FileMode.Open))
            {
                using (FileStream outStream = new FileStream(outFile, FileMode.Create))
                {
                    SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
                    encoder.SetCoderProperties(propIDs, properties);
                    encoder.WriteCoderProperties(outStream);
                    Int64 fileSize;
                    if (eos || stdInMode)
                        fileSize = -1;
                    else
                        fileSize = inStream.Length;
                    for (int i = 0; i < 8; i++)
                        outStream.WriteByte((Byte)(fileSize >> (8 * i)));
                    encoder.Code(inStream, outStream, -1, -1, null);
                }
            }

        }

        public static void DecompressFileLZMA(string inFile, string outFile)
        {
            using (FileStream input = new FileStream(inFile, FileMode.Open))
            {
                using (FileStream output = new FileStream(outFile, FileMode.Create))
                {
                    SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();

                    byte[] properties = new byte[5];
                    if (input.Read(properties, 0, 5) != 5)
                        throw (new Exception("input .lzma is too short"));
                    decoder.SetDecoderProperties(properties);

                    long outSize = 0;
                    for (int i = 0; i < 8; i++)
                    {
                        int v = input.ReadByte();
                        if (v < 0)
                            throw (new Exception("Can't Read 1"));
                        outSize |= ((long)(byte)v) << (8 * i);
                    }
                    long compressedSize = input.Length - input.Position;

                    decoder.Code(input, output, compressedSize, outSize, null);
                }
            }
        }

        public static void Test()
        {
            CompressFileLZMA("DiscUtils.pdb", "DiscUtils.pdb.7z");
            DecompressFileLZMA("DiscUtils.pdb.7z", "DiscUtils.pdb2");
        }
    }
}

15
Lưu ý rằng đây là nén / giải nén LZMA thuần túy. Định dạng tệp 7zip là một lớp bên trên cho phép đóng gói nhiều tệp cùng với tên tệp / đường dẫn và siêu dữ liệu tệp khác.
redcalx

1
@redcalx là đúng. Bất kỳ ai có một manh mối làm thế nào để xử lý lớp trên, 7zip? Tham khảo bài đăng SO khác sẽ rất tuyệt :)
Christopher J Smith

8

Tôi đã sử dụng sdk.

ví dụ:

using SevenZip.Compression.LZMA;
private static void CompressFileLZMA(string inFile, string outFile)
{
   SevenZip.Compression.LZMA.Encoder coder = new SevenZip.Compression.LZMA.Encoder();

   using (FileStream input = new FileStream(inFile, FileMode.Open))
   {
      using (FileStream output = new FileStream(outFile, FileMode.Create))
      {
          coder.Code(input, output, -1, -1, null);
          output.Flush();
      }
   }
}

7
Và bạn sẽ giải nén tập tin như thế nào? Tôi đã cố gắng làm điều tương tự bằng cách sử dụng SevenZip.Compression.LZMA.Decoder và gọi nó bằng Mã (stream1, stream2, -1, -1, null); Điều đó đã đưa ra một ngoại lệ dữ liệu từ khuôn khổ.
Karsten

3
 string zipfile = @"E:\Folderx\NPPES.zip";
 string folder = @"E:\TargetFolderx";

 ExtractFile(zipfile,folder);
public void ExtractFile(string source, string destination)
        {
            // If the directory doesn't exist, create it.
            if (!Directory.Exists(destination))
                Directory.CreateDirectory(destination);

            //string zPath = ConfigurationManager.AppSettings["FileExtactorEXE"];
          //  string zPath = Properties.Settings.Default.FileExtactorEXE; ;

            string zPath=@"C:\Program Files\7-Zip\7zG.exe";

            try
            {
                ProcessStartInfo pro = new ProcessStartInfo();
                pro.WindowStyle = ProcessWindowStyle.Hidden;
                pro.FileName = zPath;
                pro.Arguments = "x \"" + source + "\" -o" + destination;
                Process x = Process.Start(pro);
                x.WaitForExit();
            }
            catch (System.Exception Ex) { }
        }

Chỉ cần Cài đặt 7 zip từ nguồn và chuyển tham số vào phương thức.

Cảm ơn. Hãy thích câu trả lời.


Điều này làm việc cho tôi trong một dịch vụ windows với 7za.exe
Marco Duindam

1

Tôi sử dụng mã này

                string PZipPath = @"C:\Program Files\7-Zip\7z.exe";
                string sourceCompressDir = @"C:\Test";
                string targetCompressName = @"C:\Test\abc.zip";
                string CompressName = targetCompressName.Split('\\').Last();
                string[] fileCompressList = Directory.GetFiles(sourceCompressDir, "*.*");

                    if (fileCompressList.Length == 0)
                    {
                        MessageBox.Show("No file in directory", "Important Message");
                        return;
                    }
                    string filetozip = null;
                    foreach (string filename in fileCompressList)
                    {
                        filetozip = filetozip + "\"" + filename + " ";
                    }

                    ProcessStartInfo pCompress = new ProcessStartInfo();
                    pCompress.FileName = PZipPath;
                    if (chkRequestPWD.Checked == true)
                    {
                        pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" " + filetozip + " -mx=9" + " -p" + tbPassword.Text;
                    }
                    else
                    {
                        pCompress.Arguments = "a -tzip \"" + targetCompressName + "\" \"" + filetozip + "\" -mx=9";
                    }
                    pCompress.WindowStyle = ProcessWindowStyle.Hidden;
                    Process x = Process.Start(pCompress);
                    x.WaitForExit();

1

Cài đặt gói NuGet có tên SevenZipSharp.Interop

Sau đó:

SevenZipBase.SetLibraryPath(@".\x86\7z.dll");
var compressor = new SevenZip.SevenZipCompressor();
var filesToCompress = Directory.GetFiles(@"D:\data\");
compressor.CompressFiles(@"C:\archive\abc.7z", filesToCompress);

Tôi đã thử thêm tệp vào kho lưu trữ 7z hiện có với nó và tệp lưu trữ bị hỏng.
Địa lý

1

Một số thông tin kiểm tra bổ sung trên mã @Orwellophile bằng cách sử dụng tệp văn bản 17,9MB.
Việc sử dụng các giá trị thuộc tính trong ví dụ mã "nguyên trạng" sẽ có tác động tiêu cực LỚN đến hiệu suất, mất 14,16 giây .

Đặt các thuộc tính như sau sẽ thực hiện công việc tương tự ở 3,91 giây (tức là kho lưu trữ sẽ có cùng thông tin vùng chứa: bạn có thể giải nén và kiểm tra kho lưu trữ bằng 7zip nhưng không có thông tin tên tệp)

7zip gốc 2 giây.

CoderPropID[] propIDs =  {
  //CoderPropID.DictionarySize,
  //CoderPropID.PosStateBits,
  //CoderPropID.LitContextBits,
  //CoderPropID.LitPosBits,
  //CoderPropID.Algorithm,
  //CoderPropID.NumFastBytes,
  //CoderPropID.MatchFinder,
  CoderPropID.EndMarker
};
object[] properties = {
  //(Int32)(dictionary),
  //(Int32)(posStateBits),
  //(Int32)(litContextBits),
  //(Int32)(litPosBits),
  //(Int32)(algorithm),
  //(Int32)(numFastBytes),
  //mf,
  eos
};

Tôi đã thực hiện một thử nghiệm khác bằng cách sử dụng 7zip gốc và một tệp sao lưu SQL 1,2GB (.bak)
7zip (nén tối đa): 1 phút
LZMA SDK (@Orwellophile với thuộc tính-setting ở trên): 12:26 phút :-(
Outputfile có cùng kích thước .

Vì vậy, tôi đoán bản thân tôi sẽ sử dụng một giải pháp dựa trên công cụ c / c ++, tức là gọi tệp thực thi 7zip từ c # hoặc sử dụng ink-box / SevenZipSharp , là một trình bao bọc xung quanh tệp dll 7zip c / c ++, và có vẻ như trở thành ngã ba mới nhất của SevenZipSharp. Chưa thử nghiệm trình bao bọc, nhưng tôi hy vọng nó hoạt động giống như 7zip gốc. Nhưng hy vọng nó sẽ cung cấp khả năng nén luồng mà bạn rõ ràng là không thể nếu bạn gọi exe trực tiếp. Nếu không, tôi đoán không có lợi ích gì so với việc gọi exe. Trình bao bọc có một số phụ thuộc bổ sung vì vậy nó sẽ không làm cho dự án đã xuất bản của bạn "sạch" hơn.

Nhân tiện, có vẻ như nhóm .Net Core đang xem xét triển khai LZMA trong lớp system.io trong .Core ver. 5, điều đó sẽ rất tuyệt!

(Tôi biết đây là loại bình luận chứ không phải câu trả lời nhưng để có thể cung cấp đoạn mã thì đó không thể là bình luận)


0

Cách dễ nhất là làm việc với các tệp .zip thay vì .7z và sử dụng Dot Net Zip

Khi tắt các lệnh 7zip để bao gồm các vấn đề khác như đặc quyền của người dùng, tôi đã gặp sự cố với SevenZipSharp.

Private Function CompressFile(filename As String) As Boolean
Using zip As New ZipFile()
    zip.AddFile(filename & ".txt", "")
    zip.Save(filename & ".zip")
End Using

Return File.Exists(filename & ".zip")
End Function

0

SharpCompress theo ý kiến ​​của tôi là một trong những thư viện nén thông minh nhất hiện có. Nó hỗ trợ LZMA (7-zip), dễ sử dụng và đang được phát triển tích cực.

Vì nó đã hỗ trợ phát trực tuyến LZMA, nên tiếc là tại thời điểm viết bài, nó chỉ hỗ trợ đọc lưu trữ 7-zip. NHƯNG văn bản lưu trữ nằm trong danh sách việc cần làm của họ (xem readme). Đối với người đọc trong tương lai: Kiểm tra để nhận trạng thái hiện tại tại đây: https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.