/// <summary> /// Creates a file on the file system with the entry?s contents and the specified name. /// The last write time of the file is set to the entry?s last write time. /// This method does allows overwriting of an existing file with the same name. /// </summary> /// /// <exception cref="UnauthorizedAccessException">The caller does not have the required permission.</exception> /// <exception cref="ArgumentException">destinationFileName is a zero-length string, contains only whitespace, /// or contains one or more invalid characters as defined by InvalidPathChars. -or- destinationFileName specifies a directory.</exception> /// <exception cref="ArgumentNullException">destinationFileName is null.</exception> /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.</exception> /// <exception cref="DirectoryNotFoundException">The path specified in destinationFileName is invalid /// (for example, it is on an unmapped drive).</exception> /// <exception cref="IOException">destinationFileName exists and overwrite is false. /// -or- An I/O error has occurred. /// -or- The entry is currently open for writing. /// -or- The entry has been deleted from the archive.</exception> /// <exception cref="NotSupportedException">destinationFileName is in an invalid format /// -or- The ZipArchive that this entry belongs to was opened in a write-only mode.</exception> /// <exception cref="InvalidDataException">The entry is missing from the archive or is corrupt and cannot be read /// -or- The entry has been compressed using a compression method that is not supported.</exception> /// <exception cref="ObjectDisposedException">The ZipArchive that this entry belongs to has been disposed.</exception> /// <param name="destinationFileName">The name of the file that will hold the contents of the entry. /// The path is permitted to specify relative or absolute path information. /// Relative path information is interpreted as relative to the current working directory.</param> /// <param name="overwrite">True to indicate overwrite.</param> public static void ExtractToFile(this ZipArchiveEntry source, string destinationFileName, bool overwrite) { if (source == null) throw new ArgumentNullException(nameof(source)); if (destinationFileName == null) throw new ArgumentNullException(nameof(destinationFileName)); // Rely on FileStream's ctor for further checking destinationFileName parameter FileMode fMode = overwrite ? FileMode.Create : FileMode.CreateNew; using (Stream fs = new FileStream(destinationFileName, fMode, FileAccess.Write, FileShare.None, bufferSize: 0x1000, useAsync: false)) { using (Stream es = source.OpenWrite()) es.CopyTo(fs); } File.SetLastWriteTime(destinationFileName, source.LastWriteTime.DateTime); }
internal static ZipArchiveEntry DoCreateEntryFromFile(ZipArchive destination, string sourceFileName, string entryName, CompressionLevel? compressionLevel) { if (destination == null) throw new ArgumentNullException(nameof(destination)); if (sourceFileName == null) throw new ArgumentNullException(nameof(sourceFileName)); if (entryName == null) throw new ArgumentNullException(nameof(entryName)); // Checking of compressionLevel is passed down to DeflateStream and the IDeflater implementation // as it is a pluggable component that completely encapsulates the meaning of compressionLevel. // Argument checking gets passed down to FileStream's ctor and CreateEntry using (Stream fs = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 0x1000, useAsync: false)) { ZipArchiveEntry entry = compressionLevel.HasValue ? destination.CreateEntry(entryName, compressionLevel.Value) : destination.CreateEntry(entryName); DateTime lastWrite = File.GetLastWriteTime(sourceFileName); // If file to be archived has an invalid last modified time, use the first datetime representable in the Zip timestamp format // (midnight on January 1, 1980): if (lastWrite.Year < 1980 || lastWrite.Year > 2107) lastWrite = new DateTime(1980, 1, 1, 0, 0, 0); entry.LastWriteTime = lastWrite; using (Stream es = entry.OpenWrite()) fs.CopyTo(es); return entry; } }