コード例 #1
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();
                    }
                }
            }
        }
コード例 #2
0
ファイル: Form1.cs プロジェクト: janip1/CsharpZip
        /// <summary>
        /// Metoda, ki se pokliče, ko kliknemo na gumb Razširi. Odpre saveFileDialog in prebere kam bomo datoteko
        /// shranili.
        /// OPOMBA: metoda še ne deluje 100% pravilno.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnExtract_Click(object sender, EventArgs e)
        {
            filesList = new StringCollection();

            FolderBrowserDialog fbd = new FolderBrowserDialog();

            if (fileExplorer.SelectedItems.Count > 0 && fbd.ShowDialog() == DialogResult.OK)
            {
                // Pridobi shranjevalno pot
                string savePath = fbd.SelectedPath;

                foreach (ListViewItem item in fileExplorer.SelectedItems)
                {
                    string file = item.SubItems[0].Text;

                    // Preveri katera oblika datoteke je: ZIP, TAR, GZIP ali TAR.BZ2
                    if (Path.GetExtension(txtPath.Text) == ".zip")
                    {
                        ZipFile  zip   = Ionic.Zip.ZipFile.Read(txtPath.Text);
                        ZipEntry entry = zip[file];
                        if (zip[file].UsesEncryption == true)
                        {
                            PasswordPrompt passWin = new PasswordPrompt();
                            passWin.ShowDialog();

                            zip.Password = passWin.pass;
                            try
                            {
                                entry.ExtractWithPassword(savePath, passWin.pass);
                            }
                            catch (BadPasswordException)
                            {
                                if (MessageBox.Show("Napačno geslo", "Napaka", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Retry)
                                {
                                    passWin.ShowDialog();
                                }
                            }
                        }

                        string enExists = savePath + @"\" + entry.FileName;

                        if (File.Exists(enExists))
                        {
                            if (MessageBox.Show("Datoteka " + file + " že obstaja. Ali jo želite zamenjati?", "Datoteka obstaja", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
                            {
                                entry.Extract(savePath, ExtractExistingFileAction.OverwriteSilently);
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            entry.Extract(savePath);
                        }
                    }

                    else if (Path.GetExtension(txtPath.Text) == ".tar")
                    {
                        byte[]         outBuffer = new byte[4096];
                        TarInputStream tar       = new TarInputStream(new FileStream(txtPath.Text, FileMode.Open, FileAccess.Read));
                        TarEntry       curEntry  = tar.GetNextEntry();
                        while (curEntry != null)
                        {
                            if (curEntry.Name == file)
                            {
                                FileStream   fs = new FileStream(savePath + @"\" + curEntry.Name, FileMode.Create, FileAccess.Write);
                                BinaryWriter bw = new BinaryWriter(fs);
                                tar.Read(outBuffer, 0, (int)curEntry.Size);
                                bw.Write(outBuffer, 0, outBuffer.Length);
                                bw.Close();
                            }
                            curEntry = tar.GetNextEntry();
                        }
                        tar.Close();
                    }

                    else if (Path.GetExtension(txtPath.Text) == ".bz2")
                    {
                        Stream           str      = new FileStream(txtPath.Text, FileMode.Open, FileAccess.Read);
                        BZip2InputStream bzStr    = new BZip2InputStream(str);
                        TarInputStream   tar      = new TarInputStream(bzStr);
                        TarEntry         curEntry = tar.GetNextEntry();
                        while (curEntry != null)
                        {
                            if (curEntry.Name == file)
                            {
                                byte[]       outBuffer = new byte[curEntry.Size];
                                FileStream   fs        = new FileStream(savePath + @"\" + curEntry.Name, FileMode.Create, FileAccess.Write);
                                BinaryWriter bw        = new BinaryWriter(fs);
                                tar.Read(outBuffer, 0, (int)curEntry.Size);
                                bw.Write(outBuffer, 0, outBuffer.Length);
                                bw.Close();
                            }
                            curEntry = tar.GetNextEntry();
                        }
                        tar.Close();
                    }

                    else if (Path.GetExtension(txtPath.Text) == ".tgz")
                    {
                        Stream          str   = new FileStream(txtPath.Text, FileMode.Open, FileAccess.Read);
                        GZipInputStream gzStr = new GZipInputStream(str);
                        TarInputStream  tar   = new TarInputStream(gzStr);

                        TarEntry curEntry = tar.GetNextEntry();
                        while (curEntry != null)
                        {
                            if (curEntry.Name == file)
                            {
                                byte[]       outBuffer = new byte[curEntry.Size];
                                FileStream   fs        = new FileStream(savePath + @"\" + curEntry.Name, FileMode.Create, FileAccess.Write);
                                BinaryWriter bw        = new BinaryWriter(fs);
                                tar.Read(outBuffer, 0, (int)curEntry.Size);
                                bw.Write(outBuffer, 0, outBuffer.Length);
                                bw.Close();
                            }
                            curEntry = tar.GetNextEntry();
                        }
                        tar.Close();
                    }
                }
            }
            else
            {
                MessageBox.Show("Nobena datoteka ni bila izbrana. Prosimo izberite datoteke.", "Napaka", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }