sz.cs

来自「全功能c#编译器」· CS 代码 · 共 1,131 行 · 第 1/3 页

CS
1,131
字号
//------------------------------------------------------------------------------
//
// sz - A command line archiver using SharpZipLib for actual compression
//      Currently only creates Zip archives.
//
// Copyright 2004 John Reilly
//
//------------------------------------------------------------------------------

// Define test to add more detailed Console.WriteLine style information
// #define TEST

// Define this to get deeper detail on option handling
// #define OPTIONTEST

namespace SharpZip {

	using System;
	using System.IO;
	using System.Collections;
	using System.Text;
	using System.Globalization;
	using System.Diagnostics;
	using System.Reflection;

	using ICSharpCode.SharpZipLib.Zip;	
	using ICSharpCode.SharpZipLib.Zip.Compression;
	using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
	
	/// <summary>
	/// A command line archiver using the SharpZipLib compression library
	/// </summary>
	public class SharpZipArchiver {
		
		enum Overwrite {
			Prompt,
			Never,
			Always
		}
		
		/// <summary>
		/// Base constructor - initializes all fields to default values
		/// </summary>
		public SharpZipArchiver()
		{
		}

		/// <summary>
		/// Has user already seen help output?
		/// </summary>
		bool seenHelp;
		
		/// <summary>
		/// File specification possibly with wildcards from command line
		/// </summary>
		ArrayList fileSpecs = new ArrayList();
		
		/// <summary>
		/// Deflate compression level
		/// </summary>
		int    compressionLevel = Deflater.DEFAULT_COMPRESSION;
		
		/// <summary>
		/// Create entries for directories with no files
		/// </summary>
		bool   addEmptyDirectoryEntries;
		
		/// <summary>
		/// Apply operations recursively
		/// </summary>
		bool   recursive;

		/// <summary>
		/// Use ZipFile class for listing entries
		/// </summary>
		bool useZipFileWhenListing;
		
		/// <summary>
		/// Use relative path information
		/// </summary>
		bool   relativePathInfo;
		
		/// <summary>
		/// Operate silently
		/// </summary>
		bool   silent;
		
		/// <summary>
		/// Use store rather than deflate when adding files, not likely to be used much
		/// but it does exercise the option as the library supports it
		/// </summary>
		bool   useZipStored;

		/// <summary>
		/// Restore file date and time to that stored in zip file on extraction
		/// </summary>
		bool restoreDateTime;
		
		/// <summary>
		/// Overwrite files handling
		/// </summary>
		Overwrite   overwriteFiles = Overwrite.Prompt;

		/// <summary>
		/// Optional password for archive
		/// </summary>
		string password;
		
		/// <summary>
		/// prefix to remove when creating relative path names
		/// </summary>
		string removablePathPrefix;
		
		/// <summary>
		/// Where things will go
		/// </summary>
		string targetOutputDirectory;

		// TODO full CRUD really required for Zip files.

		/// <summary>
		/// Kinds of thing we know how to do, full CRUD would be great!!
		/// </summary>
		enum Operation {
			Create,     // add files to new archive
			Extract,    // extract files from existing archive
			List        // show contents of existing archive
		}
		
		/// <summary>
		/// What to do based on parsed command line arguments
		/// </summary>
		Operation operation = Operation.List;

		/// <summary>
		/// Determine if string is numeric [0-9]+
		/// </summary>
		/// <param name="rhs">string to test</param>
		/// <returns>true iff rhs is numeric</returns>
		bool IsNumeric(string rhs)
		{
			bool result;
			if (rhs != null && rhs.Length > 0) {
				result = true;
				for (int i = 0; i < rhs.Length; ++i) {
					if (char.IsDigit(rhs[i]) == false) {
						result = false;
						break;
					}
				}
			} else {
				result = false;
			}
			return result;
		}

		/// <summary>
		/// Parse command line arguments.
		/// This is fairly flexible without using any custom classes.  Arguments and options can appear
		/// in any order and are case insensitive.  Arguments for options are signalled with an '='
		/// as in -demo=argument, sometimes the '=' can be omitted as well secretly.
		/// Grouping of single character options is supported.
		/// 
		/// The actual arguments and their handling is however a grab bag of ad-hoc things and its a bit messy.  Could be a 
		/// bit more rigorous about how things are done.  Up side is almost anything is/can be allowed
		/// </summary>		
		/// <returns>
		/// true if arguments are valid such that processing should continue
		/// </returns>
		bool SetArgs(string[] args) {
			bool result = true;
			int argIndex = 0;
			
			while (argIndex < args.Length) {
				if (args[argIndex][0] == '-' || args[argIndex][0] == '/') {
					
					string option = args[argIndex].Substring(1).ToLower();
					string optArg = "";
	
					int parameterIndex = option.IndexOf('=');
	
					if (parameterIndex >= 0)
					{
						if (parameterIndex < option.Length - 1) {
							optArg = option.Substring(parameterIndex + 1);
						}
						option = option.Substring(0, parameterIndex);
					}

#if OPTIONTEST
					Console.WriteLine("args index [{0}] option [{1}] argument [{2}]", argIndex, option, optArg);
#endif				
					if (option.Length == 0) {
						System.Console.Error.WriteLine("Invalid argument (0}", args[argIndex]);
						result = false;
					}
					else {
						int optionIndex = 0;
						while (optionIndex < option.Length) {
#if OPTIONTEST
							Console.WriteLine("optionIndex {0}", optionIndex);
#endif				
							switch(option[optionIndex]) {
								case '-': // long option
									optionIndex = option.Length;
									
									switch (option) {
										case "-create":
											operation = Operation.Create;
											break;
										
										case "-list":
											operation = Operation.List;
											useZipFileWhenListing = true;
											break;
	
										case "-extract":
											operation = Operation.Extract;
											if (optArg.Length > 0) {
												targetOutputDirectory = optArg;
											}
											break;
	
										case "-info":
											ShowEnvironment();
											break;
										
										case "-emptydirs":
											addEmptyDirectoryEntries = true;
											break;
	
										case "-extractdir":
											if (optArg.Length > 0) {
												targetOutputDirectory = optArg;
											} else {
												result = false;
												System.Console.Error.WriteLine("Invalid extractdir " + args[argIndex]);
											}
											break;
										
										case "-encoding":
											if (optArg.Length > 0) {
												if (IsNumeric(optArg)) {
													try {
														int enc = int.Parse(optArg);
														if (Encoding.GetEncoding(enc) != null) {
#if OPTIONTEST
															Console.WriteLine("Encoding set to {0}", enc);
#endif				
															ZipConstants.DefaultCodePage = enc;
														} else {
															result = false;
															System.Console.Error.WriteLine("Invalid encoding " + args[argIndex]);
														}
													}
													catch (Exception) {
														result = false;
														System.Console.Error.WriteLine("Invalid encoding " + args[argIndex]);
													}
												} else {
													try {
														ZipConstants.DefaultCodePage = Encoding.GetEncoding(optArg).CodePage;
													}
													catch (Exception) {
														result = false;
														System.Console.Error.WriteLine("Invalid encoding " + args[argIndex]);
													}
												}
											} else {
												result = false;
												System.Console.Error.WriteLine("Missing encoding parameter");
											}
											break;
										
										case "-store":
											useZipStored = true;
											break;
										
										case "-deflate":
											useZipStored = false;
											break;
										
										case "-version":
											ShowVersion();
											break;
										
										case "-help":
											ShowHelp();
											break;
			
										case "-restore-dates":
											restoreDateTime = true;
											break;
										
										default:
											System.Console.Error.WriteLine("Invalid long argument " + args[argIndex]);
											result = false;
											break;
									}
									break;
								
								case '?':
									ShowHelp();
									break;
								
								case 's':
									if (optionIndex != 0) {
										result = false;
										System.Console.Error.WriteLine("-s cannot be in a group");
									} else {
										if (optArg.Length > 0) {
											password = optArg;
										} else if (option.Length > 1) {
											password = option.Substring(1);
										} else {
											System.Console.Error.WriteLine("Missing argument to " + args[argIndex]);
										}
									}
									optionIndex = option.Length;
									break;
	
								case 'c':
									operation = Operation.Create;
									break;
								
								case 'e':
									if (optionIndex != 0) {
										result = false;
										System.Console.Error.WriteLine("-e cannot be in a group");
									} else {
										optionIndex = option.Length;
										if (optArg.Length > 0) {
											try {
												compressionLevel = int.Parse(optArg);
											}
											catch (Exception) {
												System.Console.Error.WriteLine("Level invalid");
											}
										}
									}
									optionIndex = option.Length;
									break;
								
								case 'o':
									optionIndex += 1;
									overwriteFiles = optionIndex < option.Length ? (option[optionIndex] == '+') ? Overwrite.Always : Overwrite.Never : Overwrite.Never;
									break;
								
								case 'p':
									relativePathInfo = true;
									break;
								
								case 'q':
									silent = true;
									if (overwriteFiles == Overwrite.Prompt) {
										overwriteFiles = Overwrite.Never;
									}
									break;
	
								case 'r':
									recursive = true;
									break;
	
								case 'v':
									operation = Operation.List;
									break;
	
								case 'x':
									if (optionIndex != 0) {
										result = false;
										System.Console.Error.WriteLine("-x cannot be in a group");
									} else {
										operation = Operation.Extract;
										if (optArg.Length > 0) {
											targetOutputDirectory = optArg;
										}
									}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?