c#压缩解压缩cab文件
2018-07-20 来源:open-open
CabDotNet源代码单文件版,支持cab压缩解压缩
压缩cab文件
using System; using System.IO; using System.Runtime.InteropServices; using CabWrapper; using CabDotNet; // Jim Mischel <jim@mischel.com>, 11/21/2004 namespace testfci { class Class1 { // When a CAB file reaches this size, a new CAB will be created // automatically. This is useful for fitting CAB files onto disks. // // If you want to create just one huge CAB file with everything in // it, change this to a very very large number. private const int MediaSize = 300000; // When a folder has this much compressed data inside it, // automatically flush the folder. // // Flushing the folder hurts compression a little bit, but // helps random access significantly. private const int FolderThreshold = 900000; // Compression type to use private const FciCompression CompressionType = FciCompression.MsZip; // Our internal state // // The FCI APIs allow us to pass back a state pointer of our own internal class ClientState { internal int totalCompressedSize; /* total compressed size so far */ internal int totalUncompressedSize; /* total uncompressed size so far */ } [STAThread] static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("TESTFCI - Demonstrates how to use the FCI library API calls\n"); Console.WriteLine("Usage: TESTFCI file1 [+] [file2] [+] [file3] ...\n"); Console.WriteLine("Where <file1>...<fileN> are input files, and a + forces a folder boundary)"); Console.WriteLine("Output cabinets are named C:\\TEST1.CAB, C:\\TEST2.CAB, ...\n"); Console.WriteLine(" e.g. testfci test.dat source.c test.c + baloon.bmp cabbage.bmp\n"); return; } if (doFciTest(args)) Console.WriteLine(@"TESTFCI was successful, cabinets created on C:\"); else Console.WriteLine("TESTFCI failed"); } static bool doFciTest(string[] args) { // our client state ClientState cs = new ClientState(); cs.totalCompressedSize = 0; cs.totalUncompressedSize = 0; bool returnResult = true; CabCompressor cabComp = new CabCompressor(); try { setCabParameters(cabComp); cabComp.UserData = cs; // setup event handlers cabComp.NextCabinet += new NextCabinetEventHandler(cabComp_NextCabinet); cabComp.FilePlaced += new FilePlacedEventHandler(cabComp_FilePlaced); cabComp.FileAdded += new ProgressEventHandler(cabComp_FileAdded); cabComp.FolderComplete += new ProgressEventHandler(cabComp_FolderComplete); cabComp.CabinetComplete += new ProgressEventHandler(cabComp_CabinetComplete); // add each file foreach (string filename in args) { // Flush the folder? if (filename == "+") { cabComp.FlushFolder(); // continue with next file name continue; } // Don't store path information in the cabinet file string strippedName = Path.GetFileName(filename); cabComp.AddFile(filename, strippedName, false, CompressionType); } // All done adding files. Flush the cabinet. // This will automatically flush the folder first. cabComp.FlushCabinet(); Console.Write(" \r"); } catch (Exception ex) { Console.WriteLine(ex); returnResult = false; } finally { cabComp.Dispose(); } return returnResult; } static void setCabParameters(CabCompressor cabComp) { cabComp.CabInfo.MaxCabinetSize = MediaSize; cabComp.CabInfo.MaxFolderSize = FolderThreshold; // Don't reserve space for any extensions cabComp.CabInfo.HeaderReserve = 0; cabComp.CabInfo.FolderReserve = 0; cabComp.CabInfo.DataReserve = 0; // We use this to create the cabinet name cabComp.CabInfo.CabinetNumber = 1; // If you want to use disk names, use this to count disks cabComp.CabInfo.DiskNumber = 0; // Choose your own SetId cabComp.CabInfo.SetId = 12345; // Only important if CABs are spanning multiple disks, // in which case you will want to use a real disk name. // // Can be left as an empty string. cabComp.CabInfo.DiskName = "MyDisk"; // where to store the created CAB files cabComp.CabInfo.CabPath = @"e:\cabdotnet\trash\"; // store name of first CAB file cabComp.CabInfo.CabName = storeCabName(cabComp.CabInfo.CabinetNumber); } static string storeCabName(int iCab) { return string.Format("TEST{0}.CAB", iCab); } public static void cabComp_NextCabinet(object sender, NextCabinetEventArgs e) { // Cabinet counter has been incremented already by FCI // Store next cabinet name string cabName = storeCabName(e.CabInfo.CabinetNumber); e.CabInfo.CabName = cabName; // You could change the disk name here too, if you wanted e.Result = true; } public static void cabComp_FilePlaced(object sender, FilePlacedEventArgs e) { Console.WriteLine(" placed file '{0}' (size {1}) on cabinet '{2}'", e.FileName, e.FileSize, e.CabInfo.CabName); if (e.Continuation) Console.WriteLine(" (Above file is a later segment of a continued file)"); e.Result = 0; } public static void cabComp_FileAdded(object sender, ProgressEventArgs e) { ClientState cs = (ClientState)e.UserData; cs.totalCompressedSize += e.CompressedBlockSize; cs.totalUncompressedSize += e.UncompressedBlockSize; Console.Write( "Compressing: {0} -> {1} \r", cs.totalUncompressedSize, cs.totalCompressedSize ); e.Result = 0; } public static void cabComp_FolderComplete(object sender, ProgressEventArgs e) { int percentage = GetPercentage(e.FolderBytesCopied, e.FolderSize); Console.Write("Copying folder to cabinet: {0}% \r", percentage); e.Result = 0; } private static int GetPercentage(int a, int b) { if (b == 0) return 0; return ((a*100)/b); } public static void cabComp_CabinetComplete(object sender, ProgressEventArgs e) { Console.Write("Estimated cabinet size = {0}. Actual size = {1}", e.EstimatedCabSize, e.ActualCabSize); e.Result = 0; } } }
解压缩cab文件
using System; using System.IO; using System.Runtime.InteropServices; using CabDotNet; using CabWrapper; // Jim Mischel <jim@mischel.com>, 11/21/2004 namespace testfdi { class Class1 { private static string destinationDirectory = string.Empty; [STAThread] static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine( "TESTFDI - Demonstrates how to use the CabDecompressor interface.\n\n" + "Usage: TESTFDI cabinet dest_dir\n\n" + "Where <cabinet> is the name of a cabinet file, and <dest_dir>\n" + "is the destination for the files extracted\n\n" + " e.g. testfdi c:\\test1.cab c:\\\n"); return; } destinationDirectory = args[1]; if (doFdiTest(args[0])) Console.WriteLine("TestFdi was successful."); else Console.WriteLine("TestFdi failed."); } static bool doFdiTest(string cabinetFullPath) { using (CabDecompressor decomp = new CabDecompressor()) { // setup event handlers decomp.NotifyCabinetInfo += new NotifyEventHandler(decomp_NotifyCabinetInfo); decomp.NotifyCloseFile += new NotifyEventHandler(decomp_NotifyCloseFile); decomp.NotifyCopyFile += new NotifyEventHandler(decomp_NotifyCopyFile); decomp.NotifyEnumerate += new NotifyEventHandler(decomp_NotifyEnumerate); decomp.NotifyNextCabinet += new NotifyEventHandler(decomp_NotifyNextCabinet); decomp.NotifyPartialFile += new NotifyEventHandler(decomp_NotifyPartialFile); FdiCabinetInfo cabInfo = new FdiCabinetInfo(); using (FileStream fs = new FileStream(cabinetFullPath, FileMode.Open)) { if (!decomp.IsCabinetFile(fs, cabInfo)) { Console.WriteLine("File is not a cabinet."); return false; } // The file is a cabinet. Display some info. Console.WriteLine( "Information on cabinet file '{0}'\n" + " Total length of cabinet file : {1}\n" + " Number of folders in cabinet : {2}\n" + " Number of files in cabinet : {3}\n" + " Cabinet set ID : {4}\n" + " Cabinet number in set : {5}\n" + " RESERVE area in cabinet? : {6}\n" + " Chained to prev cabinet? : {7}\n" + " Chained to next cabinet? : {8}\n", cabinetFullPath, cabInfo.Length, cabInfo.FolderCount, cabInfo.FileCount, cabInfo.SetId, cabInfo.CabinetNumber, cabInfo.HasReserve, cabInfo.HasPrev, cabInfo.HasNext); } // extract path and filename string cabinetName = Path.GetFileName(cabinetFullPath); string cabinetPath = Path.GetDirectoryName(cabinetFullPath); if (cabinetPath != string.Empty) cabinetPath = cabinetPath + Path.DirectorySeparatorChar; // let's copy some files! if (!decomp.ExtractFiles(cabinetFullPath)) { Console.WriteLine("FdiCopy failed. Error code {0}", decomp.ErrorInfo.FdiErrorCode); return false; } return true; } } public static void decomp_NotifyCabinetInfo(object sender, NotifyEventArgs e) { Console.WriteLine("Cabinet Info" + " Next cabinet = {0}\n" + " Next disk = {1}\n" + " Cabinet path = {2}\n" + " Cabinet set id = {3}\n" + " Cabinet # in set = {4}", e.args.str1, e.args.str2, e.args.CabinetPathName, e.args.SetId, e.args.CabinetNumber); e.Result = 0; } public static void decomp_NotifyPartialFile(object sender, NotifyEventArgs e) { Console.WriteLine("Partial File\n" + " Name of continued file = {0}\n" + " Name of cabinet where file starts = {1}\n" + " Name of disk where file starts = {2}", e.args.str1, e.args.str2, e.args.CabinetPathName); e.Result = 0; } public static void decomp_NotifyCopyFile(object sender, NotifyEventArgs e) { Console.Write("Copy File\n" + " File name in cabinet = {0}\n" + " Uncompressed file size = {1}\n" + " Copy this file? (y/n): ", e.args.str1, e.args.Size); string response = "Y"; do { response = Console.ReadLine().ToUpper(); } while (response != "Y" && response != "N"); if (response == "Y") { int err = 0; string destFilename = destinationDirectory + e.args.str1; IntPtr fHandle = CabIO.FileOpen(destFilename, FileAccess.Write, FileShare.ReadWrite, FileMode.Create, ref err); e.Result = (int)fHandle; } else { e.Result = 0; } } public static void decomp_NotifyCloseFile(object sender, NotifyEventArgs e) { Console.WriteLine("Close File Info\n" + " File name in cabinet = {0}", e.args.str1); string fname = destinationDirectory + e.args.str1; // TODO: Most of this function probably should be encapsulated in the parent object. int err = 0; CabIO.FileClose(e.args.FileHandle, ref err, null); // set file date and time DateTime fileDateTime = FCntl.DateTimeFromDosDateTime(e.args.FileDate, e.args.FileTime); File.SetCreationTime(fname, fileDateTime); File.SetLastWriteTime(fname, fileDateTime); // get relevant file attributes and set attributes on the file FileAttributes fa = FCntl.FileAttributesFromFAttrs(e.args.FileAttributes); File.SetAttributes(fname, fa); e.Result = 1; } public static void decomp_NotifyNextCabinet(object sender, NotifyEventArgs e) { Console.WriteLine("Next Cabinet\n" + " Name of next cabinet where file continued = {0}\n" + " Name of next disk where file continued = {1}\n" + " Cabinet path name = {2}\n", e.args.str1, e.args.str2, e.args.str3); e.Result = 0; } public static void decomp_NotifyEnumerate(object sender, NotifyEventArgs e) { } } }
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。
上一篇:c#农历日历类
下一篇:Struts简单入门
最新资讯
热门推荐