public void Extract(string baseDirectory) { string targetFileName = Path.Combine(baseDirectory, this.FileName); using (MemoryStream ms = new MemoryStream(this.FileData)) { using (DeflateStream input = new DeflateStream(ms, CompressionMode.Decompress)) { // ensure the target path exists if (!Directory.Exists(Path.GetDirectoryName(targetFileName))) { Directory.CreateDirectory(Path.GetDirectoryName(targetFileName)); } using (FileStream output = new FileStream(targetFileName, FileMode.CreateNew)) { byte[] bytes = new byte[4096]; while (true) { int bytesRead = input.Read(bytes, 0, bytes.Length); if (bytesRead > 0) { output.Write(bytes, 0, bytesRead); } else { break; } } } // We may have to adjust the last modified time to compensate // for differences in how the .NET Base Class Library deals // with daylight saving time (DST) versus how the Windows // filesystem deals with daylight saving time. if (LastModified.IsDaylightSavingTime()) { DateTime AdjustedLastModified = LastModified + new TimeSpan(1, 0, 0); File.SetLastWriteTime(targetFileName, AdjustedLastModified); } else { File.SetLastWriteTime(targetFileName, LastModified); } } } }
public void Extract(string basedir) { string TargetFile = System.IO.Path.Combine(basedir, FileName); using (System.IO.MemoryStream memstream = new System.IO.MemoryStream(_FileData)) { using (System.IO.Compression.DeflateStream input = new System.IO.Compression.DeflateStream(memstream, System.IO.Compression.CompressionMode.Decompress)) { // ensure the target path exists if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(TargetFile))) { System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(TargetFile)); } using (System.IO.FileStream output = new System.IO.FileStream(TargetFile, System.IO.FileMode.CreateNew)) { //BinaryWriter w = new BinaryWriter(fs); byte[] bytes = new byte[4096]; int n; n = 1; // anything non-zero while (n != 0) { n = input.Read(bytes, 0, bytes.Length); if (n > 0) { output.Write(bytes, 0, n); } } } if (LastModified.IsDaylightSavingTime()) { System.IO.File.SetLastWriteTime(TargetFile, LastModified.AddHours(1)); } else { System.IO.File.SetLastWriteTime(TargetFile, LastModified); } } } }
// pass in either basedir or s, but not both. // In other words, you can extract to a stream or to a directory, but not both! private void Extract(string basedir, System.IO.Stream s) { string TargetFile = null; if (basedir != null) { TargetFile = System.IO.Path.Combine(basedir, FileName); // check if a directory if ((IsDirectory) || (FileName.EndsWith("/"))) { if (!System.IO.Directory.Exists(TargetFile)) { System.IO.Directory.CreateDirectory(TargetFile); } return; } } else if (s != null) { if ((IsDirectory) || (FileName.EndsWith("/"))) { // extract a directory to streamwriter? nothing to do! return; } } else { throw new Exception("Invalid input."); } using (System.IO.MemoryStream memstream = new System.IO.MemoryStream(_FileData)) { System.IO.Stream input = null; try { if (CompressedSize == UncompressedSize) { // the System.IO.Compression.DeflateStream class does not handle uncompressed data. // so if an entry is not compressed, then we just translate the bytes directly. input = memstream; } else { input = new System.IO.Compression.DeflateStream(memstream, System.IO.Compression.CompressionMode.Decompress); } if (TargetFile != null) { // ensure the target path exists if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(TargetFile))) { System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(TargetFile)); } } System.IO.Stream output = null; try { if (TargetFile != null) { if ((OverwriteOnExtract) && (System.IO.File.Exists(TargetFile))) { System.IO.File.Delete(TargetFile); } output = new System.IO.FileStream(TargetFile, System.IO.FileMode.CreateNew); } else { output = s; } byte[] bytes = new byte[4096]; int n; if (_Debug) { Console.WriteLine("{0}: _FileData.Length= {1}", TargetFile, _FileData.Length); Console.WriteLine("{0}: memstream.Position: {1}", TargetFile, memstream.Position); n = _FileData.Length; if (n > 1000) { n = 500; Console.WriteLine("{0}: truncating dump from {1} to {2} bytes...", TargetFile, _FileData.Length, n); } for (int j = 0; j < n; j += 2) { if ((j > 0) && (j % 40 == 0)) { System.Console.WriteLine(); } System.Console.Write(" {0:X2}", _FileData[j]); if (j + 1 < n) { System.Console.Write("{0:X2}", _FileData[j + 1]); } } System.Console.WriteLine("\n"); } n = 1; // anything non-zero while (n != 0) { if (_Debug) { Console.WriteLine("{0}: about to read...", TargetFile); } n = input.Read(bytes, 0, bytes.Length); if (_Debug) { Console.WriteLine("{0}: got {1} bytes", TargetFile, n); } if (n > 0) { if (_Debug) { Console.WriteLine("{0}: about to write...", TargetFile); } output.Write(bytes, 0, n); } } } finally { // we only close the output stream if we opened it. if ((output != null) && (TargetFile != null)) { output.Close(); output.Dispose(); } } if (TargetFile != null) { // We may have to adjust the last modified time to compensate // for differences in how the .NET Base Class Library deals // with daylight saving time (DST) versus how the Windows // filesystem deals with daylight saving time. See // http://blogs.msdn.com/oldnewthing/archive/2003/10/24/55413.aspx for some context. // in a nutshell: Daylight savings time rules change regularly. In // 2007, for example, the inception week of DST changed. In 1977, // DST was in place all year round. in 1945, likewise. And so on. // Win32 does not attempt to guess which time zone rules were in // effect at the time in question. It will render a time as // "standard time" and allow the app to change to DST as necessary. // .NET makes a different choice. // ------------------------------------------------------- // Compare the output of FileInfo.LastWriteTime.ToString("f") with // what you see in the property sheet for a file that was last // written to on the other side of the DST transition. For example, // suppose the file was last modified on October 17, during DST but // DST is not currently in effect. Explorer's file properties // reports Thursday, October 17, 2003, 8:45:38 AM, but .NETs // FileInfo reports Thursday, October 17, 2003, 9:45 AM. // Win32 says, "Thursday, October 17, 2002 8:45:38 AM PST". Note: // Pacific STANDARD Time. Even though October 17 of that year // occurred during Pacific Daylight Time, Win32 displays the time as // standard time because that's what time it is NOW. // .NET BCL assumes that the current DST rules were in place at the // time in question. So, .NET says, "Well, if the rules in effect // now were also in effect on October 17, 2003, then that would be // daylight time" so it displays "Thursday, October 17, 2003, 9:45 // AM PDT" - daylight time. // So .NET gives a value which is more intuitively correct, but is // also potentially incorrect, and which is not invertible. Win32 // gives a value which is intuitively incorrect, but is strictly // correct. // ------------------------------------------------------- // With this adjustment, I add one hour to the tweaked .NET time, if // necessary. That is to say, if the time in question had occurred // in what the .NET BCL assumed to be DST (an assumption that may be // wrong given the constantly changing DST rules). if (LastModified.IsDaylightSavingTime()) { DateTime AdjustedLastModified = LastModified + new System.TimeSpan(1, 0, 0); System.IO.File.SetLastWriteTime(TargetFile, AdjustedLastModified); } else { System.IO.File.SetLastWriteTime(TargetFile, LastModified); } } } finally { // we only close the output stream if we opened it. // we cannot use using() here because in some cases we do not want to Dispose the stream! if ((input != null) && (input != memstream)) { input.Close(); input.Dispose(); } } } }