sz.cs

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

CS
1,131
字号
		}

		ZipOutputStream outputStream;

		/// <summary>
		/// Add a file assuming the output is seekable
		/// </summary>		
		// TODO Add equivalent for non-seekable output
		void AddFileSeekableOutput(string file, string entryPath, int maximumBufferSize)
		{
			ZipEntry entry = new ZipEntry(entryPath);
			FileInfo fileInfo = new FileInfo(file);
			entry.DateTime = fileInfo.LastWriteTime; // File.GetLastWriteTime(file); // or DateTime.Now or whatever, for now use the file
			entry.ExternalFileAttributes = (int)fileInfo.Attributes;
			entry.Size = fileInfo.Length;

			if (useZipStored) {
				entry.CompressionMethod = CompressionMethod.Stored;
			} else {
				entry.CompressionMethod = CompressionMethod.Deflated;
			}

			System.IO.FileStream fileStream = System.IO.File.OpenRead(file);

			try {
				byte[] transferBuffer;
				if (fileStream.Length > maximumBufferSize)
					transferBuffer = new byte[maximumBufferSize];
				else
					transferBuffer = new byte[fileStream.Length];

				outputStream.PutNextEntry(entry);

				int bytesRead;
				do {
					bytesRead = fileStream.Read(transferBuffer, 0, transferBuffer.Length);
					outputStream.Write(transferBuffer, 0, bytesRead);
				}
				while (bytesRead > 0);
			}
			finally {
				fileStream.Close();
			}
		}
		
		/// <summary>
		/// Add file to archive
		/// </summary>
		/// <param name="fileName">file to add</param>
		/// <param name="bufferSize">size of buffer to use with file</param>
		void AddFile(string fileName, int bufferSize) {
#if TEST
			Console.WriteLine("AddFile {0}", fileName);
#endif			
			
			if (File.Exists(fileName)) {
				string entryName = CookZipEntryName(fileName);
				
				if (silent == false) {
					Console.Write(" " + entryName);
				}
			
				AddFileSeekableOutput(fileName, entryName, bufferSize);
				
				if (silent == false) {
					Console.WriteLine("");
				}
			} else {
				Console.Error.WriteLine("No such file exists {0}", fileName);
			}
			
			
		}
	
		/// <summary>
		/// Add an entry for a folder or directory
		/// </summary>
		/// <param name="folderName">The name of the folder to add</param>
		void AddFolder(string folderName)
		{
#if TEST
			Console.WriteLine("AddFolder {0}", folderName);
#endif			
			folderName = CookZipEntryName(folderName);
			if (folderName.Length == 0 || folderName[folderName.Length - 1] != '/')
				folderName = folderName + '/';
	
			ZipEntry zipEntry = new ZipEntry(folderName);
			outputStream.PutNextEntry(zipEntry);
		}
	
		/// <summary>
		/// Compress contents of folder
		/// </summary>
		/// <param name="basePath">The folder to compress</param>
		/// <param name="recursive">If true process recursively</param>
		/// <param name="searchPattern">Pattern to match for files</param>
		/// <returns>Number of entries added</returns>
		int CompressFolder(string basePath, bool recursive, string searchPattern)
		{
			int result = 0;
#if TEST
			System.Console.Out.WriteLine("CompressFolder basepath {0}  pattern {1}", basePath, searchPattern);
#endif
			string [] names = Directory.GetFiles(basePath, searchPattern);
			
			foreach (string fileName in names) {
				AddFile(fileName, 8192);
				++result;
			}
		
			if (names.Length == 0 && addEmptyDirectoryEntries) {
				AddFolder(basePath);
				++result;
			}
		
			if (recursive) {
				names = Directory.GetDirectories(basePath);
				foreach (string folderName in names) {
					result += CompressFolder(folderName, recursive, searchPattern);
				}
			}
			return result;
		}
	
		/// <summary>
		/// Create archives based on specifications passed and internal state
		/// </summary>		
		void Create(ArrayList fileSpecs)
		{
			string zipFileName = fileSpecs[0] as string;
			if (Path.GetExtension(zipFileName).Length == 0)
				zipFileName = Path.ChangeExtension(zipFileName, ".zip");
			
			fileSpecs.RemoveAt(0);

			if (overwriteFiles == Overwrite.Never && File.Exists(zipFileName)) {
				System.Console.Error.WriteLine("File {0} already exists", zipFileName);
				return;
			}

			int totalEntries = 0;
			
			using (FileStream stream = File.Create(zipFileName)) {
				outputStream = new ZipOutputStream(stream);
				try {
					if (password != null && password.Length > 0) {
						outputStream.Password = password;
					}
					
					outputStream.SetLevel(compressionLevel);
					foreach(string spec in fileSpecs) {
						string fileName = Path.GetFileName(spec);
						string pathName = Path.GetDirectoryName(spec);
						
						if (pathName == null || pathName.Length == 0) {
							pathName = Path.GetFullPath(".");
							if (relativePathInfo == true)
								removablePathPrefix = pathName;
						} else {
							pathName = Path.GetFullPath(pathName);
							// TODO for paths like ./txt/*.txt the prefix should be fullpath for .
							// for z:txt/*.txt should be fullpath for z:.
							if (relativePathInfo == true) {
								removablePathPrefix = pathName;
							}
						}
						
						
						// TODO wildcards arent full supported by this
						if (recursive || fileName.IndexOf('*') >= 0 || fileName.IndexOf('?') >= 0) {
							
							// TODO this allows possible conflict in filenames that are added to Zip file
							// as part of different file specs.
							// how to resolve this, could leave for decompression to solve, or try and fix at create time
							
							totalEntries += CompressFolder(pathName, recursive, fileName);
						} else {
							AddFile(pathName + @"\" + fileName, 8192);
							++totalEntries;
						}
					}
					
					if (totalEntries == 0) {
						Console.Out.WriteLine("File created has no entries!");
					}
				} finally {
					outputStream.Close();
					outputStream = null;
				}
			}
		}

		/// <summary>
		/// Decompress a file
		/// </summary>
		/// <param name="fileName">File to decompress</param>
		/// <param name="targetDir">Directory to create output in</param>
		/// <returns>true iff all has been done successfully</returns>
		bool DecompressFile(string fileName, string targetDir)
		{
			bool result = true;
		
	
			try {
				using (ZipInputStream inputStream = new ZipInputStream(File.OpenRead(fileName))) {
					if (password != null)
						inputStream.Password = password;
		
					ZipEntry theEntry;
		
					while ((theEntry = inputStream.GetNextEntry()) != null) {
						
						// try and sort out the correct place to save this entry
						string entryFileName;
						
						if (Path.IsPathRooted(theEntry.Name)) {
							entryFileName = Path.Combine(Path.GetDirectoryName(theEntry.Name), Path.GetFileName(theEntry.Name));
						} else {
							entryFileName = theEntry.Name;
						}
						string targetName = Path.Combine(targetDir, entryFileName);
						
						string fullPath = Path.GetDirectoryName(Path.GetFullPath(targetName));
#if TEST
						Console.WriteLine("Decompress targetfile name " + entryFileName);
						Console.WriteLine("Decompress targetpath " + fullPath);
#endif						
						
						// Could be an option or parameter to allow failure or try creation
						if (Directory.Exists(fullPath) == false)
						{
							try {
								Directory.CreateDirectory(fullPath);
							}
							catch {
								return false;
							}
						} else if (overwriteFiles == Overwrite.Prompt) {
							if (File.Exists(targetName) == true) {
								Console.Write("File " + targetName + " already exists.  Overwrite? ");
								
								// TODO sort out the complexities of Read so single key presses can be used
								string readValue;
								try {
									readValue = Console.ReadLine();
								}
								catch {
									readValue = null;
								}
								
								if (readValue == null || readValue.ToLower() != "y") {
#if TEST
									Console.WriteLine("Skipped!");
#endif						
									continue;
								}
							}
						}
		
					
						if (entryFileName.Length > 0) {
#if TEST
							Console.WriteLine("Extracting...");
#endif						
							FileStream streamWriter = File.Create(targetName);
						
							try {
								byte[] data = new byte[4096];
								int size;
					
								do {
									size = inputStream.Read(data, 0, data.Length);
									streamWriter.Write(data, 0, size);
								} while (size > 0);
							}
							finally {
								streamWriter.Close();
							}
							
							if (restoreDateTime) {
								File.SetLastWriteTime(targetName, theEntry.DateTime);
							}
						}
					}
					inputStream.Close();
				}
			}
			catch (Exception except) {
				result = false;
				Console.Error.WriteLine(except.Message + " Failed to unzip file");
			}
		
			return result;
		}
		
		/// <summary>
		/// Extract archives based on user input
		/// Allows simple wildcards to specify multiple archives
		/// </summary>
		void Extract(ArrayList fileSpecs)
		{
			if (targetOutputDirectory == null || targetOutputDirectory.Length == 0) {
				targetOutputDirectory = @".\";
			}
			
			foreach(string spec in fileSpecs) {
				
				string [] names;
				if (spec.IndexOf('*') >= 0 || spec.IndexOf('?') >= 0) {
					string pathName = Path.GetDirectoryName(spec);
					
					if (pathName == null || pathName.Length == 0) {
						pathName = @".\";
					}
					names = Directory.GetFiles(pathName, Path.GetFileName(spec));
				} else {
					names = new string[] { spec };
				}

				foreach (string fileName in names) {				
					if (File.Exists(fileName) == false) {
						Console.Error.WriteLine("No such file exists {0}", spec);
					} else {
						DecompressFile(fileName, targetOutputDirectory);
					}
				}
			}
		}

		/// <summary>
		/// Parse command line arguments and 'execute' them.
		/// </summary>		
		void Execute(string[] args) {
			if (SetArgs(args)) {
				if (fileSpecs.Count == 0) {
					if (silent == false) {
						Console.Out.WriteLine("Nothing to do");
					}
				}
				else {
					switch (operation) {
						case Operation.List:
							List(fileSpecs);
							break;
						
						case Operation.Create:
							Create(fileSpecs);
							break;
						
						case Operation.Extract:
							Extract(fileSpecs);
							break;
					}
				}
			} else {
				if (silent == false) {
					ShowHelp();
				}
			}
		}
		
		/// <summary>
		/// Entry point for program, creates archiver and runs it
		/// </summary>
		/// <param name="args">
		/// Command line argument to process
		/// </param>
		public static void Main(string[] args) {
		
			SharpZipArchiver sza = new SharpZipArchiver();
			sza.Execute(args);
		}
	}
}

⌨️ 快捷键说明

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