public void Progress_ReadFile() { Directory.SetCurrentDirectory(TopLevelDir); string zipFileToCreate = Path.Combine(TopLevelDir, "Progress_ReadFile.zip"); string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); var files = TestUtilities.GenerateFilesFlat(dirToZip); using (ZipFile zip = new ZipFile()) { zip.AddFiles(files); zip.Save(zipFileToCreate); } int count = TestUtilities.CountEntries(zipFileToCreate); Assert.IsTrue(count>0); var options = new ReadOptions { StatusMessageWriter = new StringWriter(), ReadProgress = ReadProgress1 }; using (ZipFile zip = ZipFile.Read(zipFileToCreate, options)) { // this should be fine zip.RemoveEntry(zip[1]); zip.Save(); } TestContext.WriteLine(options.StatusMessageWriter.ToString()); Assert.AreEqual<Int32>(count, TestUtilities.CountEntries(zipFileToCreate)+1); }
/// <summary> /// Reads a zip file archive from the named filesystem file using the /// specified options. /// </summary> /// /// <remarks> /// <para> /// This version of the <c>Read()</c> method allows the caller to pass /// in a <c>TextWriter</c> an <c>Encoding</c>, via an instance of the /// <c>ReadOptions</c> class. The <c>ZipFile</c> is read in using the /// specified encoding for entries where UTF-8 encoding is not /// explicitly specified. /// </para> /// </remarks> /// /// <example> /// /// <para> /// This example shows how to read a zip file using the Big-5 Chinese /// code page (950), and extract each entry in the zip file, while /// sending status messages out to the Console. /// </para> /// /// <para> /// For this code to work as intended, the zipfile must have been /// created using the big5 code page (CP950). This is typical, for /// example, when using WinRar on a machine with CP950 set as the /// default code page. In that case, the names of entries within the /// Zip archive will be stored in that code page, and reading the zip /// archive must be done using that code page. If the application did /// not use the correct code page in ZipFile.Read(), then names of /// entries within the zip archive would not be correctly retrieved. /// </para> /// /// <code lang="C#"> /// string zipToExtract = "MyArchive.zip"; /// string extractDirectory = "extract"; /// var options = new ReadOptions /// { /// StatusMessageWriter = System.Console.Out, /// Encoding = System.Text.Encoding.GetEncoding(950) /// }; /// using (ZipFile zip = ZipFile.Read(zipToExtract, options)) /// { /// foreach (ZipEntry e in zip) /// { /// e.Extract(extractDirectory); /// } /// } /// </code> /// /// /// <code lang="VB"> /// Dim zipToExtract as String = "MyArchive.zip" /// Dim extractDirectory as String = "extract" /// Dim options as New ReadOptions /// options.Encoding = System.Text.Encoding.GetEncoding(950) /// options.StatusMessageWriter = System.Console.Out /// Using zip As ZipFile = ZipFile.Read(zipToExtract, options) /// Dim e As ZipEntry /// For Each e In zip /// e.Extract(extractDirectory) /// Next /// End Using /// </code> /// </example> /// /// /// <example> /// /// <para> /// This example shows how to read a zip file using the default /// code page, to remove entries that have a modified date before a given threshold, /// sending status messages out to a <c>StringWriter</c>. /// </para> /// /// <code lang="C#"> /// var options = new ReadOptions /// { /// StatusMessageWriter = new System.IO.StringWriter() /// }; /// using (ZipFile zip = ZipFile.Read("PackedDocuments.zip", options)) /// { /// var Threshold = new DateTime(2007,7,4); /// // We cannot remove the entry from the list, within the context of /// // an enumeration of said list. /// // So we add the doomed entry to a list to be removed later. /// // pass 1: mark the entries for removal /// var MarkedEntries = new System.Collections.Generic.List<ZipEntry>(); /// foreach (ZipEntry e in zip) /// { /// if (e.LastModified < Threshold) /// MarkedEntries.Add(e); /// } /// // pass 2: actually remove the entry. /// foreach (ZipEntry zombie in MarkedEntries) /// zip.RemoveEntry(zombie); /// zip.Comment = "This archive has been updated."; /// zip.Save(); /// } /// // can now use contents of sw, eg store in an audit log /// </code> /// /// <code lang="VB"> /// Dim options as New ReadOptions /// options.StatusMessageWriter = New System.IO.StringWriter /// Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip", options) /// Dim Threshold As New DateTime(2007, 7, 4) /// ' We cannot remove the entry from the list, within the context of /// ' an enumeration of said list. /// ' So we add the doomed entry to a list to be removed later. /// ' pass 1: mark the entries for removal /// Dim MarkedEntries As New System.Collections.Generic.List(Of ZipEntry) /// Dim e As ZipEntry /// For Each e In zip /// If (e.LastModified < Threshold) Then /// MarkedEntries.Add(e) /// End If /// Next /// ' pass 2: actually remove the entry. /// Dim zombie As ZipEntry /// For Each zombie In MarkedEntries /// zip.RemoveEntry(zombie) /// Next /// zip.Comment = "This archive has been updated." /// zip.Save /// End Using /// ' can now use contents of sw, eg store in an audit log /// </code> /// </example> /// /// <exception cref="System.Exception"> /// Thrown if the zipfile cannot be read. The implementation of /// this method relies on <c>System.IO.File.OpenRead</c>, which /// can throw a variety of exceptions, including specific /// exceptions if a file is not found, an unauthorized access /// exception, exceptions for poorly formatted filenames, and so /// on. /// </exception> /// /// <param name="fileName"> /// The name of the zip archive to open. /// This can be a fully-qualified or relative pathname. /// </param> /// /// <param name="options"> /// The set of options to use when reading the zip file. /// </param> /// /// <returns>The ZipFile instance read from the zip archive.</returns> /// /// <seealso cref="ZipFile.Read(Stream, ReadOptions)"/> /// public static ZipFile Read(string fileName, ReadOptions options) { if (options == null) throw new ArgumentNullException("options"); return Read(fileName, options.StatusMessageWriter, options.Encoding, options.ReadProgress); }
/// <summary> /// Reads a zip file archive from the given stream using the /// specified options. /// </summary> /// /// <remarks> /// /// <para> /// When reading from a file, it's probably easier to just use /// <see cref="ZipFile.Read(String, /// ReadOptions)">ZipFile.Read(String, ReadOptions)</see>. This /// overload is useful when when the zip archive content is /// available from an already-open stream. The stream must be /// open and readable and seekable when calling this method. The /// stream is left open when the reading is completed. /// </para> /// /// <para> /// Reading of zip content begins at the current position in the /// stream. This means if you have a stream that concatenates /// regular data and zip data, if you position the open, readable /// stream at the start of the zip data, you will be able to read /// the zip archive using this constructor, or any of the ZipFile /// constructors that accept a <see cref="System.IO.Stream" /> as /// input. Some examples of where this might be useful: the zip /// content is concatenated at the end of a regular EXE file, as /// some self-extracting archives do. (Note: SFX files produced /// by DotNetZip do not work this way; they can be read as normal /// ZIP files). Another example might be a stream being read from /// a database, where the zip content is embedded within an /// aggregate stream of data. /// </para> /// </remarks> /// /// <param name="zipStream">the stream containing the zip data.</param> /// /// <param name="options"> /// The set of options to use when reading the zip file. /// </param> /// /// <exception cref="System.Exception"> /// Thrown if the zip archive cannot be read. /// </exception> /// /// <returns>The ZipFile instance read from the stream.</returns> /// /// <seealso cref="ZipFile.Read(String, ReadOptions)"/> /// public static ZipFile Read(Stream zipStream, ReadOptions options) { if (options == null) throw new ArgumentNullException("options"); return Read(zipStream, options.StatusMessageWriter, options.Encoding, options.ReadProgress); }
public void Extract_ExistingFile() { string zipFileToCreate = Path.Combine(TopLevelDir, "Extract_ExistingFile.zip"); string sourceDir = CurrentDir; for (int i = 0; i < 3; i++) sourceDir = Path.GetDirectoryName(sourceDir); Directory.SetCurrentDirectory(TopLevelDir); string[] filenames = { Path.Combine(sourceDir, "Tools\\Zipit\\bin\\Debug\\Zipit.exe"), Path.Combine(sourceDir, "Zip\\bin\\Debug\\Ionic.Zip.dll"), Path.Combine(sourceDir, "Zip\\bin\\Debug\\Ionic.Zip.pdb"), Path.Combine(sourceDir, "Zip\\bin\\Debug\\Ionic.Zip.xml"), //Path.Combine(SourceDir, "AppNote.txt") }; int j = 0; using (ZipFile zip = new ZipFile()) { for (j = 0; j < filenames.Length; j++) zip.AddFile(filenames[j], ""); zip.Comment = "This is a Comment On the Archive"; zip.Save(zipFileToCreate); } BasicVerifyZip(zipFileToCreate); Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filenames.Length, "The zip file created has the wrong number of entries."); TestContext.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - - - - -"); TestContext.WriteLine("1. first extract - this should succeed"); var options = new ReadOptions { StatusMessageWriter = new StringWriter() }; using (ZipFile zip = ZipFile.Read(zipFileToCreate, options)) { for (j = 0; j < filenames.Length; j++) { var f = Path.GetFileName(filenames[j]); zip[f].Extract("unpack", ExtractExistingFileAction.Throw); } } TestContext.WriteLine(options.StatusMessageWriter.ToString()); TestContext.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - - - - -"); TestContext.WriteLine("2. extract again - DoNotOverwrite"); options.StatusMessageWriter = new StringWriter(); using (ZipFile zip = ZipFile.Read(zipFileToCreate, options)) { for (j = 0; j < filenames.Length; j++) { var f = Path.GetFileName(filenames[j]); zip[f].Extract("unpack", ExtractExistingFileAction.DoNotOverwrite); } } TestContext.WriteLine(options.StatusMessageWriter.ToString()); TestContext.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - - - - -"); TestContext.WriteLine("3. extract again - OverwriteSilently"); options.StatusMessageWriter = new StringWriter(); using (ZipFile zip = ZipFile.Read(zipFileToCreate, options)) { for (j = 0; j < filenames.Length; j++) { var f = Path.GetFileName(filenames[j]); zip[f].Extract("unpack", ExtractExistingFileAction.OverwriteSilently); } } TestContext.WriteLine(options.StatusMessageWriter.ToString()); TestContext.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - - - - -"); TestContext.WriteLine("4. extract again - InvokeExtractProgressEvent"); options.StatusMessageWriter = new StringWriter(); using (ZipFile zip = ZipFile.Read(zipFileToCreate, options)) { zip.ExtractProgress += OverwriteDecider; for (j = 0; j < filenames.Length; j++) { var f = Path.GetFileName(filenames[j]); zip[f].Extract("unpack", ExtractExistingFileAction.InvokeExtractProgressEvent); } } TestContext.WriteLine(options.StatusMessageWriter.ToString()); }
public void CodePage_UpdateZip_AlternateEncoding_wi10180() { System.Text.Encoding JIS = System.Text.Encoding.GetEncoding("shift_jis"); TestContext.WriteLine("The CP for JIS is: {0}", JIS.CodePage); ReadOptions options = new ReadOptions { Encoding = JIS }; string[] filenames = { "日本語.txt", "日本語テスト.txt" }; // three trials: one for old-style // ProvisionalAlternateEncoding, one for "AsNecessary" // and one for "Always" for (int j=0; j < 3; j++) { string zipFileToCreate = String.Format("wi10180-{0}.zip", j); // pass 1 - create it TestContext.WriteLine("Create zip, cycle {0}...", j); using (var zip = new ZipFile()) { switch (j) { case 0: #pragma warning disable 618 zip.ProvisionalAlternateEncoding = JIS; #pragma warning restore 618 break; case 1: zip.AlternateEncoding = JIS; zip.AlternateEncodingUsage = ZipOption.AsNecessary; break; case 2: zip.AlternateEncoding = JIS; zip.AlternateEncodingUsage = ZipOption.Always; break; } zip.AddEntry(filenames[0], "This is the content for entry (" + filenames[0] + ")"); TestContext.WriteLine("adding file: {0}", filenames[0]); zip.Save(zipFileToCreate); } // pass 2 - read and update it TestContext.WriteLine("Update zip..."); using (var zip0 = ZipFile.Read(zipFileToCreate, options)) { foreach (var e in zip0) { TestContext.WriteLine("existing entry name: {0} encoding: {1}", e.FileName, e.AlternateEncoding.EncodingName ); Assert.AreEqual<System.Text.Encoding> (options.Encoding, e.AlternateEncoding); } zip0.AddEntry(filenames[1], "This is more content..." + System.DateTime.UtcNow.ToString("G")); TestContext.WriteLine("adding file: {0}", filenames[1]); zip0.Save(); } // pass 3 - verify the filenames, again TestContext.WriteLine("Verify zip..."); using (var zip0 = ZipFile.Read(zipFileToCreate, options)) { foreach (string f in filenames) { Assert.AreEqual<string>(f, zip0[f].FileName, "The FileName was not expected, (cycle {0}) ", j); } } } }
public void Create_UnicodeEntries() { int i; string origComment = "This is a Unicode comment. "+ "Chinese: 弹 出 应 用 程 序 "+ "Norwegian/Danish: æøåÆØÅ. "+ "Portugese: Configurações."; string[] formats = { "弹出应用程序{0:D3}.bin", "n.æøåÆØÅ{0:D3}.bin", "Configurações-弹出-ÆØÅ-xx{0:D3}.bin" }; for (int k = 0; k < formats.Length; k++) { // create the subdirectory string subdir = Path.Combine(TopLevelDir, "files" + k); Directory.CreateDirectory(subdir); // create a bunch of files int numFilesToCreate = _rnd.Next(18) + 14; string[] filesToZip = new string[numFilesToCreate]; for (i = 0; i < numFilesToCreate; i++) { filesToZip[i] = Path.Combine(subdir, String.Format(formats[k], i)); TestUtilities.CreateAndFillFileBinary(filesToZip[i], _rnd.Next(5000) + 2000); } // create a zipfile twice, once using Unicode, once without for (int j = 0; j < 2; j++) { // select the name of the zip file string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Create_UnicodeEntries_{0}_{1}.zip", k, j)); Assert.IsFalse(File.Exists(zipFileToCreate), "The zip file '{0}' already exists.", zipFileToCreate); TestContext.WriteLine("\n\nFormat {0}, trial {1}. filename: {2}...", k, j, zipFileToCreate); string dirInArchive = String.Format("{0}-{1}", Path.GetFileName(subdir), j); using (ZipFile zip1 = new ZipFile()) { #pragma warning disable 618 zip1.UseUnicodeAsNecessary = (j == 0); #pragma warning restore 618 for (i = 0; i < filesToZip.Length; i++) { // use the local filename (not fully qualified) ZipEntry e = zip1.AddFile(filesToZip[i], dirInArchive); e.Comment = String.Format("This entry encoded with {0}", (j == 0) ? "unicode" : "the default code page."); } zip1.Comment = origComment; zip1.Save(zipFileToCreate); } // Verify the number of files in the zip Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length, "Incorrect number of entries in the zip file."); i = 0; // verify the filenames are (or are not) unicode var options = new ReadOptions { Encoding = (j == 0) ? System.Text.Encoding.UTF8 : ZipFile.DefaultEncoding }; using (ZipFile zip2 = ZipFile.Read(zipFileToCreate, options)) { foreach (ZipEntry e in zip2) { string fname = String.Format(formats[k], i); if (j == 0) { Assert.AreEqual<String>(fname, Path.GetFileName(e.FileName)); } else { Assert.AreNotEqual<String>(fname, Path.GetFileName(e.FileName)); } i++; } // according to the spec, // unicode is not supported on the zip archive comment! // But this library won't enforce that. // We will leave it up to the application. // Assert.AreNotEqual<String>(origComment, zip2.Comment); } } } }
public void Create_WithSpecifiedCodepage() { int i; CodepageTrial[] trials = { new CodepageTrial( "big5", "弹出应用程序{0:D3}.bin", true), new CodepageTrial ("big5", "您好{0:D3}.bin", false), new CodepageTrial ("gb2312", "弹出应用程序{0:D3}.bin", false), new CodepageTrial ("gb2312", "您好{0:D3}.bin", false), // insert other trials here.?? }; for (int k = 0; k < trials.Length; k++) { TestContext.WriteLine(""); TestContext.WriteLine("---------------------Trial {0}....", k); TestContext.WriteLine("---------------------codepage: {0}....", trials[k].codepage); // create the subdirectory string subdir = Path.Combine(TopLevelDir, String.Format("trial{0}-files", k)); Directory.CreateDirectory(subdir); // create a bunch of files int numFiles = _rnd.Next(3) + 3; string[] filesToZip = new string[numFiles]; for (i = 0; i < numFiles; i++) { filesToZip[i] = Path.Combine(subdir, String.Format(trials[k].filenameFormat, i)); TestUtilities.CreateAndFillFileBinary(filesToZip[i], _rnd.Next(5000) + 2000); } Directory.SetCurrentDirectory(subdir); // three cases: one for old-style // ProvisionalAlternateEncoding, one for "AsNecessary" // and one for "Always" for (int j=0; j < 3; j++) { // select the name of the zip file string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("WithSpecifiedCodepage_{0}_{1}_{2}.zip", k, j, trials[k].codepage)); TestContext.WriteLine(""); TestContext.WriteLine("---------------Creating zip, trial ({0},{1})....", k, j); using (ZipFile zip1 = new ZipFile(zipFileToCreate)) { switch (j) { case 0: #pragma warning disable 618 zip1.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(trials[k].codepage); #pragma warning restore 618 break; case 1: zip1.AlternateEncoding = System.Text.Encoding.GetEncoding(trials[k].codepage); zip1.AlternateEncodingUsage = ZipOption.AsNecessary; break; case 2: zip1.AlternateEncoding = System.Text.Encoding.GetEncoding(trials[k].codepage); zip1.AlternateEncodingUsage = ZipOption.Always; break; } for (i = 0; i < filesToZip.Length; i++) { TestContext.WriteLine("adding entry {0}", filesToZip[i]); // use the local filename (not fully qualified) ZipEntry e = zip1.AddFile(filesToZip[i], ""); e.Comment = String.Format("This entry was encoded in the {0} codepage", trials[k].codepage); } zip1.Save(); } TestContext.WriteLine("\n---------------------Extracting...."); Directory.SetCurrentDirectory(TopLevelDir); try { // verify the filenames are (or are not) unicode var options = new ReadOptions { Encoding = System.Text.Encoding.GetEncoding(trials[k].codepage) }; using (ZipFile zip2 = ZipFile.Read(zipFileToCreate, options)) { foreach (ZipEntry e in zip2) { TestContext.WriteLine("found entry {0}", e.FileName); e.Extract(String.Format("trial{0}-{1}-{2}-extract", k, j, trials[k].codepage)); } } } catch (Exception e1) { if (trials[k].exceptionExpected) TestContext.WriteLine("caught expected exception"); else throw new System.Exception("while extracting", e1); } } } TestContext.WriteLine("\n---------------------Done."); }
public void UnicodeComment_wi10392() { const string zipFileToCreate = "UnicodeComment_wi10392.zip"; const string cyrillicComment = "Hello, Привет"; TestContext.WriteLine("{0}", zipFileToCreate); TestContext.WriteLine("==== creating zip"); using (ZipFile zip1 = new ZipFile(zipFileToCreate, Encoding.UTF8)) { zip1.Comment = cyrillicComment; zip1.AddEntry("entry", "this is the content of the added entry"); zip1.Save(); } string comment2 = null; TestContext.WriteLine("==== checking zip"); var options = new ReadOptions { Encoding = Encoding.UTF8 }; using (ZipFile zip2 = ZipFile.Read(zipFileToCreate, options)) { comment2 = zip2.Comment; } Assert.AreEqual<String>(cyrillicComment, comment2, "The comments are not equal."); }