Exemple #1
0
        public FileSystemZipSegmentedStreamManager(string baseName)
        {
            _baseName     = baseName;
            _fullBaseName = ZipFileExtensions.GetFullPath(_baseName);

            var baseDir = Path.GetDirectoryName(_fullBaseName);

            _baseFolder = FileSystem.Current.GetFolderFromPathAsync(baseDir).ExecuteSync();
            if (_baseFolder == null)
            {
                var dir = Path.GetDirectoryName(_baseName);
                throw new ZipException("Bad Directory", new ArgumentException(string.Format("That folder ({0}) does not exist!", dir)));
            }
        }
        /// <summary>
        ///   Create a <c>ZipInputStream</c>, given the name of an existing zip file.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        ///   This constructor opens a <c>FileStream</c> for the given zipfile, and
        ///   wraps a <c>ZipInputStream</c> around that.  See the documentation for the
        ///   <see cref="ZipInputStream(Stream)"/> constructor for full details.
        /// </para>
        ///
        /// <para>
        ///   While the <see cref="ZipFile"/> class is generally easier
        ///   to use, this class provides an alternative to those
        ///   applications that want to read from a zipfile directly,
        ///   using a <see cref="System.IO.Stream"/>.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <param name="fileName">
        ///   The name of the filesystem file to read.
        /// </param>
        ///
        /// <example>
        ///
        ///   This example shows how to read a zip file, and extract entries, using the
        ///   <c>ZipInputStream</c> class.
        ///
        /// <code lang="C#">
        /// private void Unzip()
        /// {
        ///     byte[] buffer= new byte[2048];
        ///     int n;
        ///     using (var input= new ZipInputStream(inputFileName))
        ///     {
        ///         ZipEntry e;
        ///         while (( e = input.GetNextEntry()) != null)
        ///         {
        ///             if (e.IsDirectory) continue;
        ///             string outputPath = Path.Combine(extractDir, e.FileName);
        ///             using (var output = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
        ///             {
        ///                 while ((n= input.Read(buffer, 0, buffer.Length)) > 0)
        ///                 {
        ///                     output.Write(buffer,0,n);
        ///                 }
        ///             }
        ///         }
        ///     }
        /// }
        /// </code>
        ///
        /// <code lang="VB">
        /// Private Sub UnZip()
        ///     Dim inputFileName As String = "MyArchive.zip"
        ///     Dim extractDir As String = "extract"
        ///     Dim buffer As Byte() = New Byte(2048) {}
        ///     Using input As ZipInputStream = New ZipInputStream(inputFileName)
        ///         Dim e As ZipEntry
        ///         Do While (Not e = input.GetNextEntry Is Nothing)
        ///             If Not e.IsDirectory Then
        ///                 Using output As FileStream = File.Open(Path.Combine(extractDir, e.FileName), _
        ///                                                        FileMode.Create, FileAccess.ReadWrite)
        ///                     Dim n As Integer
        ///                     Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
        ///                         output.Write(buffer, 0, n)
        ///                     Loop
        ///                 End Using
        ///             End If
        ///         Loop
        ///     End Using
        /// End Sub
        /// </code>
        /// </example>
        internal static ZipInputStream Create(String fileName)
        {
            string fullPath = ZipFileExtensions.GetFullPath(fileName);

            var file = FileSystem.Current.GetFileFromPathAsync(fullPath).ExecuteSync();

            if (file == null)
            {
                throw new FileNotFoundException(string.Format("That file ({0}) does not exist!", fileName));
            }
            var stream = file.OpenAsync(FileAccess.Read).ExecuteSync();

            return(new ZipInputStream(stream));
        }
        /// <summary>
        ///   Create a ZipOutputStream that writes to a filesystem file.
        /// </summary>
        ///
        /// <remarks>
        ///   The <see cref="ZipFile"/> class is generally easier to use when creating
        ///   zip files. The ZipOutputStream offers a different metaphor for creating a
        ///   zip file, based on the <see cref="System.IO.Stream"/> class.
        /// </remarks>
        ///
        /// <param name="fileName">
        ///   The name of the zip file to create.
        /// </param>
        ///
        /// <example>
        ///
        ///   This example shows how to create a zip file, using the
        ///   ZipOutputStream class.
        ///
        /// <code lang="C#">
        /// private void Zipup()
        /// {
        ///     if (filesToZip.Count == 0)
        ///     {
        ///         System.Console.WriteLine("Nothing to do.");
        ///         return;
        ///     }
        ///
        ///     using (var output= new ZipOutputStream(outputFileName))
        ///     {
        ///         output.Password = "******";
        ///         output.Encryption = EncryptionAlgorithm.WinZipAes256;
        ///
        ///         foreach (string inputFileName in filesToZip)
        ///         {
        ///             System.Console.WriteLine("file: {0}", inputFileName);
        ///
        ///             output.PutNextEntry(inputFileName);
        ///             using (var input = File.Open(inputFileName, FileMode.Open, FileAccess.Read,
        ///                                          FileShare.Read | FileShare.Write ))
        ///             {
        ///                 byte[] buffer= new byte[2048];
        ///                 int n;
        ///                 while ((n= input.Read(buffer,0,buffer.Length)) > 0)
        ///                 {
        ///                     output.Write(buffer,0,n);
        ///                 }
        ///             }
        ///         }
        ///     }
        /// }
        /// </code>
        ///
        /// <code lang="VB">
        /// Private Sub Zipup()
        ///     Dim outputFileName As String = "XmlData.zip"
        ///     Dim filesToZip As String() = Directory.GetFiles(".", "*.xml")
        ///     If (filesToZip.Length = 0) Then
        ///         Console.WriteLine("Nothing to do.")
        ///     Else
        ///         Using output As ZipOutputStream = New ZipOutputStream(outputFileName)
        ///             output.Password = "******"
        ///             output.Encryption = EncryptionAlgorithm.WinZipAes256
        ///             Dim inputFileName As String
        ///             For Each inputFileName In filesToZip
        ///                 Console.WriteLine("file: {0}", inputFileName)
        ///                 output.PutNextEntry(inputFileName)
        ///                 Using input As FileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        ///                     Dim n As Integer
        ///                     Dim buffer As Byte() = New Byte(2048) {}
        ///                     Do While (n = input.Read(buffer, 0, buffer.Length) > 0)
        ///                         output.Write(buffer, 0, n)
        ///                     Loop
        ///                 End Using
        ///             Next
        ///         End Using
        ///     End If
        /// End Sub
        /// </code>
        /// </example>
        internal static ZipOutputStream Create(String fileName)
        {
            string fullPath = ZipFileExtensions.GetFullPath(fileName);

            var file = FileSystem.Current.GetFileFromPathAsync(fullPath).ExecuteSync();

            if (file == null)
            {
                var dirName = Path.GetDirectoryName(fullPath);
                var dir     = ZipEntryExtensions.CreateDirectory(dirName, true);
                file = dir.CreateFileAsync(Path.GetFileName(fileName), CreationCollisionOption.ReplaceExisting).ExecuteSync();
            }
            var stream = file.OpenAsync(FileAccess.ReadAndWrite).ExecuteSync();

            return(new ZipOutputStream(stream));
        }
Exemple #4
0
        /// <summary>
        /// Pass in either basedir or s, but not both.
        /// In other words, you can extract to a stream or to a directory (filesystem), but not both!
        /// The Password param is required for encrypted entries.
        /// </summary>
        private static void InternalExtractToBaseDir(this ZipEntry zipEntry, string baseDir, string password)
        {
            if (baseDir == null)
            {
                throw new ArgumentNullException("baseDir");
            }

            var zipFile = zipEntry.GetZipFile();

            // workitem 10355
            if (zipFile == null)
            {
                throw new InvalidOperationException("Use Extract() only with ZipFile.");
            }

            // get the full filename
            var f = ZipEntryInternal.NameInArchive(zipEntry.FileName);
            var targetFileName = zipFile.FlattenFoldersOnExtract
                ? Path.Combine(baseDir, Path.GetFileName(f))
                : Path.Combine(baseDir, f);

            // workitem 10639
            targetFileName = targetFileName.Replace('/', PortablePath.DirectorySeparatorChar);
            var fullTargetPath = ZipFileExtensions.GetFullPath(targetFileName);

            var fileExistsBeforeExtraction = false;

            try
            {
                // check if it is a directory
                if (zipEntry.IsDirectory || zipEntry.FileName.EndsWith("/"))
                {
                    CreateDirectory(fullTargetPath);
                    goto ExitTry; // all done, caller will return
                }

                // it is a file, so start the extraction
                if (FileSystem.Current.GetFileFromPathAsync(fullTargetPath).ExecuteSync() != null)
                {
                    fileExistsBeforeExtraction = true;
                    int rc = zipEntry.CheckExtractExistingFile(baseDir, targetFileName);
                    if (rc == 2)
                    {
                        goto ExitTry;          // cancel
                    }
                    if (rc == 1)
                    {
                        return;          // do not overwrite
                    }
                }

                // set up the output stream
                var tmpName = Path.GetRandomFileName();
                var tmpPath = Path.Combine(Path.GetDirectoryName(fullTargetPath), tmpName);
                var dirName = Path.GetDirectoryName(tmpPath);

                // ensure the target path exists
                var dir = CreateDirectory(dirName, true);

                // extract
                var file = dir.CreateFileAsync(tmpPath, CreationCollisionOption.ReplaceExisting).ExecuteSync();
                using (var output = file.OpenAsync(FileAccess.ReadAndWrite).ExecuteSync())
                {
                    zipEntry.ExtractWithPassword(output, password);
                }
                MoveFileInPlace(fileExistsBeforeExtraction, fullTargetPath, tmpPath);

                ExitTry :;
            }
            catch (Exception)
            {
                zipEntry.SetIOOperationCanceled(true);
                throw;
            }
            finally
            {
                if (zipEntry.IsIOOperationCanceled() && targetFileName != null)
                {
                    // An exception has occurred. If the file exists, check
                    // to see if it existed before we tried extracting.  If
                    // it did not, attempt to remove the target file. There
                    // is a small possibility that the existing file has
                    // been extracted successfully, overwriting a previously
                    // existing file, and an exception was thrown after that
                    // but before final completion (setting times, etc). In
                    // that case the file will remain, even though some
                    // error occurred.  Nothing to be done about it.
                    var file = FileSystem.Current.GetFileFromPathAsync(fullTargetPath).ExecuteSync();
                    if (file != null && !fileExistsBeforeExtraction)
                    {
                        file.DeleteAsync();
                    }
                }
            }
        }