Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DotNETFrameworkNotesForProfessionals.pdf
Скачиваний:
32
Добавлен:
20.05.2023
Размер:
1.82 Mб
Скачать

Chapter 19: Reading and writing Zip files

The ZipFile class lives in the System.IO.Compression namespace. It can be used to read from, and write to Zip files.

Section 19.1: Listing ZIP contents

This snippet will list all the filenames of a zip archive. The filenames are relative to the zip root.

using (FileStream fs = new FileStream("archive.zip", FileMode.Open)) using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Read))

{

for (int i = 0; i < archive.Entries.Count; i++)

{

Console.WriteLine($"{i}: {archive.Entries[i]}");

}

}

Section 19.2: Extracting files from ZIP files

Extracting all the files into a directory is very easy:

using (FileStream fs = new FileStream("archive.zip", FileMode.Open)) using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Read))

{

archive.ExtractToDirectory(AppDomain.CurrentDomain.BaseDirectory);

}

When the file already exists, a System.IO.IOException will be thrown.

Extracting specific files:

using (FileStream fs = new FileStream("archive.zip", FileMode.Open)) using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Read))

{

// Get a root entry file archive.GetEntry("test.txt").ExtractToFile("test_extracted_getentries.txt", true);

// Enter a path if you want to extract files from a subdirectory archive.GetEntry("sub/subtest.txt").ExtractToFile("test_sub.txt", true);

// You can also use the Entries property to find files archive.Entries.FirstOrDefault(f => f.Name ==

"test.txt")?.ExtractToFile("test_extracted_linq.txt", true);

// This will throw a System.ArgumentNullException because the file cannot be found archive.GetEntry("nonexistingfile.txt").ExtractToFile("fail.txt", true);

}

Any of these methods will produce the same result.

Section 19.3: Updating a ZIP file

To update a ZIP file, the file has to be opened with ZipArchiveMode.Update instead.

using (FileStream fs = new FileStream("archive.zip", FileMode.Open))

GoalKicker.com – .NET Framework Notes for Professionals

76

using (ZipArchive archive = new ZipArchive(fs, ZipArchiveMode.Update))

{

// Add file to root archive.CreateEntryFromFile("test.txt", "test.txt");

// Add file to subfolder archive.CreateEntryFromFile("test.txt", "symbols/test.txt");

}

There is also the option to write directly to a file within the archive:

var entry = archive.CreateEntry("createentry.txt"); using(var writer = new StreamWriter(entry.Open()))

{

writer.WriteLine("Test line");

}

GoalKicker.com – .NET Framework Notes for Professionals

77

Chapter 20: Managed Extensibility

Framework

Section 20.1: Connecting (Basic)

See the other (Basic) examples above.

using System.ComponentModel.Composition;

using System.ComponentModel.Composition.Hosting;

namespace Demo

{

public static class Program

{

public static void Main()

{

using (var catalog = new ApplicationCatalog())

using (var exportProvider = new CatalogExportProvider(catalog)) using (var container = new CompositionContainer(exportProvider))

{

exportProvider.SourceProvider = container;

UserWriter writer = new UserWriter();

//at this point, writer's userProvider field is null container.ComposeParts(writer);

//now, it should be non-null (or an exception will be thrown). writer.PrintAllUsers();

}

}

}

}

As long as something in the application's assembly search path has [Export(typeof(IUserProvider))],

UserWriter's corresponding import will be satisfied and the users will be printed.

Other types of catalogs (e.g., DirectoryCatalog) can be used instead of (or in addition to) ApplicationCatalog, to look in other places for exports that satisfy the imports.

Section 20.2: Exporting a Type (Basic)

using System.Collections.Generic; using System.Collections.ObjectModel;

using System.ComponentModel.Composition;

namespace Demo

{

[Export(typeof(IUserProvider))]

public sealed class UserProvider : IUserProvider

{

public ReadOnlyCollection<User> GetAllUsers()

{

return new List<User>

{

new User(0, "admin"), new User(1, "Dennis"),

GoalKicker.com – .NET Framework Notes for Professionals

78

new User(2, "Samantha"), }.AsReadOnly();

}

}

}

This could be defined virtually anywhere; all that matters is that the application knows where to look for it (via the ComposablePartCatalogs it creates).

Section 20.3: Importing (Basic)

using System;

using System.ComponentModel.Composition;

namespace Demo

{

public sealed class UserWriter

{

[Import(typeof(IUserProvider))] private IUserProvider userProvider;

public void PrintAllUsers()

{

foreach (User user in this.userProvider.GetAllUsers())

{

Console.WriteLine(user);

}

}

}

}

This is a type that has a dependency on an IUserProvider, which could be defined anywhere. Like the previous example, all that matters is that the application knows where to look for the matching export (via the ComposablePartCatalogs it creates).

GoalKicker.com – .NET Framework Notes for Professionals

79