📄 sz.cs
字号:
System.Console.WriteLine("Invalid argument: " + args[argIndex]);
result = false;
break;
}
++optionIndex;
}
}
}
else {
fileSpecs.Add(args[argIndex]);
}
++argIndex;
}
if (fileSpecs.Count > 0 && operation == Operation.Create) {
string checkPath = (string)fileSpecs[0];
int deviceCheck = checkPath.IndexOf(':');
#if NETCF_1_0
if (checkPath.IndexOfAny(Path.InvalidPathChars) >= 0
#else
if (checkPath.IndexOfAny(Path.GetInvalidPathChars()) >= 0
#endif
|| checkPath.IndexOf('*') >= 0 || checkPath.IndexOf('?') >= 0
|| (deviceCheck >= 0 && deviceCheck != 1)) {
Console.WriteLine("There are invalid characters in the specified zip file name");
result = false;
}
}
return result && (fileSpecs.Count > 0);
}
/// <summary>
/// Show encoding/locale information
/// </summary>
void ShowEnvironment()
{
seenHelp = true;
#if !NETCF_1_0
System.Console.WriteLine(
"Current encoding is {0}, code page {1}, windows code page {2}",
System.Console.Out.Encoding.EncodingName,
System.Console.Out.Encoding.CodePage,
System.Console.Out.Encoding.WindowsCodePage);
System.Console.WriteLine("Default code page is {0}",
Encoding.Default.CodePage);
Console.WriteLine( "Current culture LCID 0x{0:X}, {1}", CultureInfo.CurrentCulture.LCID, CultureInfo.CurrentCulture.EnglishName);
Console.WriteLine( "Current thread OEM codepage {0}", System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.OEMCodePage);
Console.WriteLine( "Current thread Mac codepage {0}", System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.MacCodePage);
Console.WriteLine( "Current thread Ansi codepage {0}", System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ANSICodePage);
#endif
}
/// <summary>
/// Display version information
/// </summary>
void ShowVersion() {
seenHelp = true;
Console.WriteLine("SharpZip Archiver v0.37 Copyright 2004 John Reilly");
#if !NETCF
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies) {
if (assembly.GetName().Name == "ICSharpCode.SharpZipLib") {
Console.WriteLine("#ZipLib v{0} {1}", assembly.GetName().Version,
assembly.GlobalAssemblyCache == true ? "Running from GAC" : "Running from DLL"
);
}
}
#endif
}
/// <summary>
/// Show help on possible options and arguments
/// </summary>
void ShowHelp()
{
if (seenHelp == true) {
return;
}
seenHelp = true;
ShowVersion();
Console.WriteLine("usage sz {options} archive files");
Console.WriteLine("");
Console.WriteLine("Options:");
Console.WriteLine("-abs Store absolute path info");
Console.WriteLine("-?, --help Show this help");
Console.WriteLine("-c --create Create new archive");
Console.WriteLine("-v List archive contents (default)");
Console.WriteLine("--list List archive contents extended format");
Console.WriteLine("-x{=dir}, --extract{=dir} Extract archive contents to dir(default .)");
Console.WriteLine("--extractdir=path Set extract directory (default .)");
Console.WriteLine("--info Show current environment information" );
Console.WriteLine("--store Store entries (default=deflate)");
Console.WriteLine("--version Show version information");
Console.WriteLine("--emptydirs Create entries for empty directories");
Console.WriteLine("--encoding=codepage|name Set code page for encoding by name or number");
#if !NETCF
Console.WriteLine("--restore-dates Restore dates on extraction");
#endif
Console.WriteLine("--delete Delete files from archive");
Console.WriteLine("--test Test archive for validity");
Console.WriteLine("--data Test archive data");
Console.WriteLine("--add Add files to archive");
Console.WriteLine("-o+ Overwrite files without prompting");
Console.WriteLine("-o- Never overwrite files");
Console.WriteLine("-p Store relative path info (default)");
Console.WriteLine("-r Recurse sub-folders");
Console.WriteLine("-q Quiet mode");
Console.WriteLine("-s=password Set archive password");
Console.WriteLine("-l=level Use compression level (0-9) when compressing");
Console.WriteLine("");
}
///<summary>
/// Calculate compression ratio as a percentage
/// Doesnt allow for expansion (ratio > 100) as the resulting strings can get huge easily
/// </summary>
int GetCompressionRatio(long packedSize, long unpackedSize)
{
int result = 0;
if (unpackedSize > 0 && unpackedSize >= packedSize) {
result = (int) Math.Round((1.0 - ((double)packedSize / (double)unpackedSize)) * 100.0);
}
return result;
}
/// <summary>
/// List zip file contents using stream
/// </summary>
/// <param name="fileName">File to list contents of</param>
void ListZip(string fileName) {
try
{
// TODO for asian/non-latin/non-proportional fonts string lengths dont work so output may not line up
const string headerTitles = "Name Length Ratio Size Date & time CRC-32";
const string headerUnderline = "--------------- ---------- ----- ---------- ------------------- --------";
FileInfo fileInfo = new FileInfo(fileName);
if (fileInfo.Exists == false) {
Console.WriteLine("No such file exists {0}", fileName);
return;
}
Console.WriteLine(fileName);
using (FileStream fileStream = File.OpenRead(fileName)) {
using (ZipInputStream stream = new ZipInputStream(fileStream)) {
if (password != null && password.Length > 0)
stream.Password = password;
int entryCount = 0;
long totalSize = 0;
ZipEntry theEntry;
while ((theEntry = stream.GetNextEntry()) != null) {
if ( theEntry.IsDirectory ) {
Console.WriteLine("Directory {0}", theEntry.Name);
continue;
}
if ( !theEntry.IsFile ) {
Console.WriteLine("Non file entry {0}", theEntry.Name);
continue;
}
if (entryCount == 0) {
Console.WriteLine(headerTitles);
Console.WriteLine(headerUnderline);
}
++entryCount;
int ratio = GetCompressionRatio(theEntry.CompressedSize, theEntry.Size);
totalSize += theEntry.Size;
if (theEntry.Name.Length > 15) {
Console.WriteLine(theEntry.Name);
Console.WriteLine(
"{0,-15} {1,10:0} {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss} {5,8:x}",
"", theEntry.Size, ratio, theEntry.CompressedSize, theEntry.DateTime, theEntry.Crc);
} else {
Console.WriteLine(
"{0,-15} {1,10:0} {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss} {5,8:x}",
theEntry.Name, theEntry.Size, ratio, theEntry.CompressedSize, theEntry.DateTime, theEntry.Crc);
}
}
if (entryCount == 0) {
Console.WriteLine("Archive is empty!");
} else {
Console.WriteLine(headerUnderline);
Console.WriteLine(
"{0,-15} {1,10:0} {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss}",
entryCount.ToString() + " entries", totalSize, GetCompressionRatio(fileInfo.Length, totalSize), fileInfo.Length, fileInfo.LastWriteTime);
}
}
}
}
catch(Exception exception)
{
Console.WriteLine("Exception during list operation: {0}", exception.Message);
}
}
/// <summary>
/// List zip file contents using ZipFile class
/// </summary>
/// <param name="fileName">File to list contents of</param>
void ListZipViaZipFile(string fileName) {
try
{
const string headerTitles = "Name Length Ratio Size Date & time CRC-32 Attr";
const string headerUnderline = "------------ ---------- ----- ---------- ------------------- -------- ------";
FileInfo fileInfo = new FileInfo(fileName);
if (fileInfo.Exists == false) {
Console.WriteLine("No such file exists {0}", fileName);
return;
}
Console.WriteLine(fileName);
int entryCount = 0;
long totalSize = 0;
using (ZipFile zipFile = new ZipFile(fileName))
{
foreach (ZipEntry theEntry in zipFile)
{
if ( theEntry.IsDirectory )
{
Console.WriteLine("Directory {0}", theEntry.Name);
}
else if ( !theEntry.IsFile )
{
Console.WriteLine("Non file entry {0}", theEntry.Name);
continue;
}
else
{
if (entryCount == 0)
{
Console.WriteLine(headerTitles);
Console.WriteLine(headerUnderline);
}
++entryCount;
int ratio = GetCompressionRatio(theEntry.CompressedSize, theEntry.Size);
totalSize += theEntry.Size;
if (theEntry.Name.Length > 12)
{
Console.WriteLine(theEntry.Name);
Console.WriteLine(
"{0,-12} {1,10:0} {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss} {5,8:x} {6,4}",
"", theEntry.Size, ratio, theEntry.CompressedSize, theEntry.DateTime, theEntry.Crc,
InterpretExternalAttributes(theEntry.HostSystem, theEntry.ExternalFileAttributes));
}
else
{
Console.WriteLine(
"{0,-12} {1,10:0} {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss} {5,8:x} {6,4}",
theEntry.Name, theEntry.Size, ratio, theEntry.CompressedSize, theEntry.DateTime, theEntry.Crc,
InterpretExternalAttributes(theEntry.HostSystem, theEntry.ExternalFileAttributes));
}
}
}
}
if (entryCount == 0) {
Console.WriteLine("Archive is empty!");
} else {
Console.WriteLine(headerUnderline);
Console.WriteLine(
"{0,-12} {1,10:0} {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss}",
entryCount.ToString() + " entries", totalSize, GetCompressionRatio(fileInfo.Length, totalSize), fileInfo.Length, fileInfo.LastWriteTime);
}
}
catch(Exception exception)
{
Console.WriteLine("Exception during list operation: {0}", exception.Message);
}
}
/// <summary>
/// Execute List operation
/// Currently only Zip files are supported
/// </summary>
/// <param name="fileSpecs">Files to list</param>
void List(ArrayList fileSpecs)
{
foreach (string spec in fileSpecs) {
string [] names;
string pathName = Path.GetDirectoryName(spec);
if ( (pathName == null) || (pathName.Length == 0) ) {
pathName = @".\";
}
names = Directory.GetFiles(pathName, Path.GetFileName(spec));
if (names.Length == 0) {
Console.WriteLine("No files found matching {0}", spec);
}
else {
foreach (string file in names) {
if (useZipFileWhenListing) {
ListZipViaZipFile(file);
} else {
ListZip(file);
}
Console.WriteLine("");
}
}
}
}
/// <summary>
/// 'Cook' a name making it acceptable as a zip entry name.
/// </summary>
/// <param name="name">name to cook</param>
/// <param name="stripPrefix">String to remove from front of name if present</param>
/// <param name="relativePath">Make names relative if true or absolute if false</param>
static public string CookZipEntryName(string name, string stripPrefix, bool relativePath)
{
#if TEST
Console.WriteLine("Cooking '{0}' prefix is '{1}'", name, stripPrefix);
#endif
if (name == null) {
return "";
}
if (stripPrefix != null && stripPrefix.Length > 0 && name.IndexOf(stripPrefix, 0) == 0) {
name = name.Substring(stripPrefix.Length);
}
if (Path.IsPathRooted(name) == true) {
// NOTE:
// for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt
name = name.Substring(Path.GetPathRoot(name).Length);
#if TEST
Console.WriteLine("Removing root info {0}", name);
#endif
}
name = name.Replace(@"\", "/");
if (relativePath == true) {
if (name.Length > 0 && (name[0] == Path.AltDirectorySeparatorChar || name[0] == Path.DirectorySeparatorChar)) {
name = name.Remove(0, 1);
}
} else {
if (name.Length > 0 && name[0] != Path.AltDirectorySeparatorChar && name[0] != Path.DirectorySeparatorChar) {
name = name.Insert(0, "/");
}
}
#if TEST
Console.WriteLine("Cooked value '{0}'", name);
#endif
return name;
}
/// <summary>
/// Make string into something acceptable as an entry name
/// </summary>
/// <param name="name">Name to 'cook'</param>
string CookZipEntryName(string name)
{
return CookZipEntryName(name, removablePathPrefix, relativePathInfo);
}
// TODO: Add equivalent for non-seekable output
/// <summary>
/// Add a file were the output is seekable
/// </summary>
void AddFileSeekableOutput(string file, string entryPath)
{
ZipEntry entry = new ZipEntry(entryPath);
FileInfo fileInfo = new FileInfo(file);
entry.DateTime = fileInfo.LastWriteTime; // 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;
}
using (System.IO.FileStream fileStream = System.IO.File.OpenRead(file))
{
outputStream.PutNextEntry(entry);
StreamUtils.Copy(fileStream, outputStream, GetBuffer());
}
}
byte[] GetBuffer()
{
if ( buffer == null )
{
buffer = new byte[bufferSize_];
}
return buffer;
}
/// <summary>
/// Add file to archive
/// </summary>
/// <param name="fileName">file to add</param>
void AddFile(string fileName) {
#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);
if (silent == false) {
Console.WriteLine("");
}
} else {
Console.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.WriteLine("CompressFolder basepath {0} pattern {1}", basePath, searchPattern);
#endif
string [] names = Directory.GetFiles(basePath, searchPattern);
foreach (string fileName in names) {
AddFile(fileName);
++result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -