📄 zf.cs
字号:
#endregion
#region Archive Listing
void ListArchiveContents(ZipFile zipFile, FileInfo fileInfo)
{
const string headerTitles = "Name Length Ratio Size Date & time CRC-32 Attr";
const string headerUnderline = "------------ ---------- ----- ---------- ------------------- -------- ------";
int entryCount = 0;
long totalCompressedSize = 0;
long totalSize = 0;
foreach (ZipEntry theEntry in zipFile)
{
if ( theEntry.IsDirectory )
{
Console.Out.WriteLine("Directory {0}", theEntry.Name);
}
else if ( !theEntry.IsFile )
{
Console.Out.WriteLine("Non file entry {0}", theEntry.Name);
continue;
}
else
{
if (entryCount == 0)
{
Console.Out.WriteLine(headerTitles);
Console.Out.WriteLine(headerUnderline);
}
++entryCount;
int ratio = GetCompressionRatio(theEntry.CompressedSize, theEntry.Size);
totalSize += theEntry.Size;
totalCompressedSize += theEntry.CompressedSize;
char cryptoDisplay = ( theEntry.IsCrypted ) ? '*' : ' ';
if (theEntry.Name.Length > 12)
{
Console.Out.WriteLine(theEntry.Name);
Console.Out.WriteLine(
"{0,-12}{7} {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),
cryptoDisplay);
}
else
{
Console.Out.WriteLine(
"{0,-12}{7} {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),
cryptoDisplay);
}
}
}
if (entryCount == 0)
{
Console.Out.WriteLine("Archive is empty!");
}
else
{
Console.Out.WriteLine(headerUnderline);
Console.Out.WriteLine(
"{0,-12} {1,10:0} {2,3}% {3,10:0} {4,10:d} {4:hh:mm:ss}",
entryCount.ToString() + " entries", totalSize, GetCompressionRatio(totalCompressedSize, totalSize), fileInfo.Length, fileInfo.LastWriteTime);
}
}
/// <summary>
/// List zip file contents using ZipFile class
/// </summary>
/// <param name="fileName">File to list contents of</param>
void ListArchiveContents(string fileName)
{
try
{
FileInfo fileInfo = new FileInfo(fileName);
if (!fileInfo.Exists)
{
Console.Error.WriteLine("No such file exists {0}", fileName);
}
else
{
Console.Out.WriteLine(fileName);
try
{
using (ZipFile zipFile = new ZipFile(fileName))
{
ListArchiveContents(zipFile, fileInfo);
}
}
catch(Exception ex)
{
Console.Out.WriteLine("Problem reading archive - '{0}'", ex.Message);
}
}
}
catch(Exception exception)
{
Console.Error.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 pathName = Path.GetDirectoryName(spec);
if ( (pathName == null) || (pathName.Length == 0) )
{
pathName = @".\";
}
string[] names = Directory.GetFiles(pathName, Path.GetFileName(spec));
if (names.Length == 0)
{
Console.Error.WriteLine("No files found matching {0}", spec);
}
else
{
foreach (string file in names)
{
ListArchiveContents(file);
}
Console.Out.WriteLine("");
}
}
}
#endregion
#region Creation
/// <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;
}
try
{
using (ZipFile zf = ZipFile.Create(zipFileName) )
{
zf.Password = password_;
zf.UseZip64 = useZip64_;
zf.BeginUpdate();
activeZipFile_ = zf;
foreach (string spec in fileSpecs)
{
// This can fail with wildcards in spec...
string path = Path.GetDirectoryName(Path.GetFullPath(spec));
string fileSpec = Path.GetFileName(spec);
zf.NameTransform = new ZipNameTransform(path);
FileSystemScanner scanner = new FileSystemScanner(WildcardToRegex(fileSpec));
scanner.ProcessFile = new ProcessFileDelegate(ProcessFile);
scanner.ProcessDirectory = new ProcessDirectoryDelegate(ProcessDirectory);
scanner.Scan(path, recursive_);
}
zf.CommitUpdate();
}
}
catch (Exception ex)
{
Console.WriteLine("Problem creating archive - '{0}'", ex.Message);
}
}
#endregion
#region Extraction
/// <summary>
/// Extract a file storing its contents.
/// </summary>
/// <param name="inputStream">The input stream to source fiel contents from.</param>
/// <param name="theEntry">The <see cref="ZipEntry"/> representing the stored file details </param>
/// <param name="targetDir">The directory to store the output.</param>
/// <returns>True iff successful; false otherwise.</returns>
bool ExtractFile(Stream inputStream, ZipEntry theEntry, string targetDir)
{
// try and sort out the correct place to save this entry
string entryFileName;
if (Path.IsPathRooted(theEntry.Name))
{
string workName = Path.GetPathRoot(theEntry.Name);
workName = theEntry.Name.Substring(workName.Length);
entryFileName = Path.Combine(Path.GetDirectoryName(workName), 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 press can be used
string readValue;
try
{
readValue = Console.ReadLine();
}
catch
{
readValue = null;
}
if ( (readValue == null) || (readValue.ToLower() != "y") )
{
return true;
}
}
}
if (entryFileName.Length > 0)
{
if ( !silent_ )
{
Console.Write("{0}", targetName);
}
using (FileStream outputStream = File.Create(targetName))
{
StreamUtils.Copy(inputStream, outputStream, GetBuffer());
}
if (restoreDateTime_)
{
File.SetLastWriteTime(targetName, theEntry.DateTime);
}
if ( !silent_ )
{
Console.WriteLine(" OK");
}
}
return true;
}
/// <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 DecompressArchive(string fileName, string targetDir)
{
bool result = true;
try
{
using (ZipFile zf = new ZipFile(fileName))
{
zf.Password = password_;
foreach ( ZipEntry entry in zf )
{
if ( entry.IsFile )
{
ExtractFile(zf.GetInputStream(entry), entry, targetDir);
}
else
{
if ( !silent_ )
{
Console.WriteLine("Skipping {0}", entry.Name);
}
}
}
if ( !silent_ )
{
Console.WriteLine("Done");
}
}
}
catch(Exception ex)
{
Console.WriteLine("Exception decompressing - '{0}'", ex);
result = false;
}
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}", fileName);
}
else
{
DecompressArchive(fileName, targetOutputDirectory_);
}
}
}
}
#endregion
#region Testing
/// <summary>
/// Handler for test result callbacks.
/// </summary>
/// <param name="status">The current <see cref="TestStatus"/>.</param>
/// <param name="message">The message applicable for this result.</param>
void TestResultHandler(TestStatus status, string message)
{
switch ( status.Operation )
{
case TestOperation.Initialising:
Console.WriteLine("Testing");
break;
case TestOperation.Complete:
Console.WriteLine("Testing complete");
break;
case TestOperation.EntryHeader:
// Not an error if message is null.
if ( message == null )
{
Console.Write("{0} - ", status.Entry.Name);
}
else
{
Console.WriteLine(message);
}
break;
case TestOperation.EntryData:
if ( message != null )
{
Console.WriteLine(message);
}
break;
case TestOperation.EntryComplete:
if ( status.EntryValid )
{
Console.WriteLine("OK");
}
break;
case TestOperation.MiscellaneousTests:
if ( message != null )
{
Console.WriteLine(message);
}
break;
}
}
/// <summary>
/// Test an archive to see if its valid.
/// </summary>
/// <param name="fileSpecs">The files to test.</param>
void Test(ArrayList fileSpecs)
{
string zipFileName = fileSpecs[0] as string;
if (Path.GetExtension(zipFileName).Length == 0)
{
zipFileName = Path.ChangeExtension(zipFileName, ".zip");
}
try
{
using (ZipFile zipFile = new ZipFile(zipFileName))
{
zipFile.Password = password_;
if ( zipFile.TestArchive(testData_, TestStrategy.FindAllErrors,
new ZipTestResultHandler(TestResultHandler)) )
{
Console.Out.WriteLine("Archive test passed");
}
else
{
Console.Out.WriteLine("Archive test failure");
}
}
}
catch(Exception ex)
{
Console.Out.WriteLine("Error list files - '{0}'", ex.Message);
}
}
#endregion
#region Deleting
/// <summary>
/// Delete entries from an archive
/// </summary>
/// <param name="fileSpecs">The file specs to operate on.</param>
void Delete(ArrayList fileSpecs)
{
string zipFileName = fileSpecs[0] as string;
if (Path.GetExtension(zipFileName).Length == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -