diff --git a/vs4win/Chapter09/Chapter09.sln b/vs4win/Chapter09/Chapter09.sln
index 9c3f4f5..e052be7 100644
--- a/vs4win/Chapter09/Chapter09.sln
+++ b/vs4win/Chapter09/Chapter09.sln
@@ -15,7 +15,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkingWithJson", "WorkingW
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ch09Ex02SerializingShapes", "Ch09Ex02SerializingShapes\Ch09Ex02SerializingShapes.csproj", "{27FA94CC-1856-4512-9D09-0214CF846311}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkingWithRandomAccess", "WorkingWithRandomAccess\WorkingWithRandomAccess.csproj", "{EFC99F8A-CB39-48BB-A70D-5D7DB0A001D6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkingWithRandomAccess", "WorkingWithRandomAccess\WorkingWithRandomAccess.csproj", "{EFC99F8A-CB39-48BB-A70D-5D7DB0A001D6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkingWithTarArchives", "WorkingWithTarArchives\WorkingWithTarArchives.csproj", "{CD1DB489-9656-4D00-ABCA-8EA975F8BE0D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -51,6 +53,10 @@ Global
{EFC99F8A-CB39-48BB-A70D-5D7DB0A001D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EFC99F8A-CB39-48BB-A70D-5D7DB0A001D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EFC99F8A-CB39-48BB-A70D-5D7DB0A001D6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CD1DB489-9656-4D00-ABCA-8EA975F8BE0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CD1DB489-9656-4D00-ABCA-8EA975F8BE0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CD1DB489-9656-4D00-ABCA-8EA975F8BE0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CD1DB489-9656-4D00-ABCA-8EA975F8BE0D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/Program.Helpers.cs b/vs4win/Chapter09/WorkingWithTarArchives/Program.Helpers.cs
new file mode 100644
index 0000000..c6ec51c
--- /dev/null
+++ b/vs4win/Chapter09/WorkingWithTarArchives/Program.Helpers.cs
@@ -0,0 +1,26 @@
+partial class Program
+{
+ static void WriteError(string message)
+ {
+ ConsoleColor previousColor = ForegroundColor;
+ ForegroundColor = ConsoleColor.Red;
+ WriteLine($"FAIL: {message}");
+ ForegroundColor = previousColor;
+ }
+
+ static void WriteWarning(string message)
+ {
+ ConsoleColor previousColor = ForegroundColor;
+ ForegroundColor = ConsoleColor.DarkYellow;
+ WriteLine($"WARN: {message}");
+ ForegroundColor = previousColor;
+ }
+
+ static void WriteInformation(string message)
+ {
+ ConsoleColor previousColor = ForegroundColor;
+ ForegroundColor = ConsoleColor.Blue;
+ WriteLine($"INFO: {message}");
+ ForegroundColor = previousColor;
+ }
+}
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/Program.cs b/vs4win/Chapter09/WorkingWithTarArchives/Program.cs
new file mode 100644
index 0000000..80e182c
--- /dev/null
+++ b/vs4win/Chapter09/WorkingWithTarArchives/Program.cs
@@ -0,0 +1,65 @@
+using System.Formats.Tar; // TarFile
+
+try
+{
+ string current = Environment.CurrentDirectory;
+ WriteInformation($"Current directory: {current}");
+
+ string sourceDirectory = Path.Combine(current, "images");
+ string destinationDirectory = Path.Combine(current, "extracted");
+ string tarFile = Path.Combine(current, "images-archive.tar");
+
+ if (!Directory.Exists(sourceDirectory))
+ {
+ WriteError($"The {sourceDirectory} directory must exist. Please create it and add some files to it.");
+ return;
+ }
+
+ if (File.Exists(tarFile))
+ {
+ // If the Tar archive file already exists then we must delete it.
+ File.Delete(tarFile);
+ WriteWarning($"{tarFile} already existed so it was deleted.");
+ }
+
+ WriteInformation(
+ $"Archiving directory: {sourceDirectory}\n To .tar file: {tarFile}");
+
+ TarFile.CreateFromDirectory(
+ sourceDirectoryName: sourceDirectory,
+ destinationFileName: tarFile,
+ includeBaseDirectory: true);
+
+ WriteInformation($"Does {tarFile} exist? {File.Exists(tarFile)}.");
+
+ if (!Directory.Exists(destinationDirectory))
+ {
+ // If the destination directory does not exist then we must create
+ // it before extracting a Tar archive to it.
+ Directory.CreateDirectory(destinationDirectory);
+ WriteWarning($"{destinationDirectory} did not exist so it was created.");
+ }
+
+ WriteInformation(
+ $"Extracting archive: {tarFile}\n To directory: {destinationDirectory}");
+
+ TarFile.ExtractToDirectory(
+ sourceFileName: tarFile,
+ destinationDirectoryName: destinationDirectory,
+ overwriteFiles: true);
+
+ if (Directory.Exists(destinationDirectory))
+ {
+ foreach (string dir in Directory.GetDirectories(destinationDirectory))
+ {
+ WriteInformation(
+ $"Extracted directory {dir} containing these files: " +
+ string.Join(',', Directory.EnumerateFiles(dir)
+ .Select(file => Path.GetFileName(file))));
+ }
+ }
+}
+catch (Exception ex)
+{
+ WriteError(ex.Message);
+}
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/WorkingWithTarArchives.csproj b/vs4win/Chapter09/WorkingWithTarArchives/WorkingWithTarArchives.csproj
new file mode 100644
index 0000000..52d7d5a
--- /dev/null
+++ b/vs4win/Chapter09/WorkingWithTarArchives/WorkingWithTarArchives.csproj
@@ -0,0 +1,45 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/images/category1.jpeg b/vs4win/Chapter09/WorkingWithTarArchives/images/category1.jpeg
new file mode 100644
index 0000000..3842ade
Binary files /dev/null and b/vs4win/Chapter09/WorkingWithTarArchives/images/category1.jpeg differ
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/images/category2.jpeg b/vs4win/Chapter09/WorkingWithTarArchives/images/category2.jpeg
new file mode 100644
index 0000000..4fea495
Binary files /dev/null and b/vs4win/Chapter09/WorkingWithTarArchives/images/category2.jpeg differ
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/images/category3.jpeg b/vs4win/Chapter09/WorkingWithTarArchives/images/category3.jpeg
new file mode 100644
index 0000000..19890b5
Binary files /dev/null and b/vs4win/Chapter09/WorkingWithTarArchives/images/category3.jpeg differ
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/images/category4.jpeg b/vs4win/Chapter09/WorkingWithTarArchives/images/category4.jpeg
new file mode 100644
index 0000000..5e0f542
Binary files /dev/null and b/vs4win/Chapter09/WorkingWithTarArchives/images/category4.jpeg differ
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/images/category5.jpeg b/vs4win/Chapter09/WorkingWithTarArchives/images/category5.jpeg
new file mode 100644
index 0000000..3a446d1
Binary files /dev/null and b/vs4win/Chapter09/WorkingWithTarArchives/images/category5.jpeg differ
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/images/category6.jpeg b/vs4win/Chapter09/WorkingWithTarArchives/images/category6.jpeg
new file mode 100644
index 0000000..067aa42
Binary files /dev/null and b/vs4win/Chapter09/WorkingWithTarArchives/images/category6.jpeg differ
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/images/category7.jpeg b/vs4win/Chapter09/WorkingWithTarArchives/images/category7.jpeg
new file mode 100644
index 0000000..a9586f1
Binary files /dev/null and b/vs4win/Chapter09/WorkingWithTarArchives/images/category7.jpeg differ
diff --git a/vs4win/Chapter09/WorkingWithTarArchives/images/category8.jpeg b/vs4win/Chapter09/WorkingWithTarArchives/images/category8.jpeg
new file mode 100644
index 0000000..3608eeb
Binary files /dev/null and b/vs4win/Chapter09/WorkingWithTarArchives/images/category8.jpeg differ
diff --git a/vscode/Chapter09/Chapter09.code-workspace b/vscode/Chapter09/Chapter09.code-workspace
index e126e57..32dbf2e 100644
--- a/vscode/Chapter09/Chapter09.code-workspace
+++ b/vscode/Chapter09/Chapter09.code-workspace
@@ -9,15 +9,15 @@
{
"path": "WorkingWithEncodings"
},
- {
- "path": "WorkingWithRandomAccess"
- },
{
"path": "WorkingWithSerialization"
},
{
"path": "WorkingWithJson"
},
+ {
+ "path": "WorkingWithTarArchives"
+ },
{
"path": "Ch09Ex02SerializingShapes"
}
diff --git a/vscode/Chapter09/WorkingWithTarArchives/Program.Helpers.cs b/vscode/Chapter09/WorkingWithTarArchives/Program.Helpers.cs
new file mode 100644
index 0000000..c6ec51c
--- /dev/null
+++ b/vscode/Chapter09/WorkingWithTarArchives/Program.Helpers.cs
@@ -0,0 +1,26 @@
+partial class Program
+{
+ static void WriteError(string message)
+ {
+ ConsoleColor previousColor = ForegroundColor;
+ ForegroundColor = ConsoleColor.Red;
+ WriteLine($"FAIL: {message}");
+ ForegroundColor = previousColor;
+ }
+
+ static void WriteWarning(string message)
+ {
+ ConsoleColor previousColor = ForegroundColor;
+ ForegroundColor = ConsoleColor.DarkYellow;
+ WriteLine($"WARN: {message}");
+ ForegroundColor = previousColor;
+ }
+
+ static void WriteInformation(string message)
+ {
+ ConsoleColor previousColor = ForegroundColor;
+ ForegroundColor = ConsoleColor.Blue;
+ WriteLine($"INFO: {message}");
+ ForegroundColor = previousColor;
+ }
+}
diff --git a/vscode/Chapter09/WorkingWithTarArchives/Program.cs b/vscode/Chapter09/WorkingWithTarArchives/Program.cs
new file mode 100644
index 0000000..80e182c
--- /dev/null
+++ b/vscode/Chapter09/WorkingWithTarArchives/Program.cs
@@ -0,0 +1,65 @@
+using System.Formats.Tar; // TarFile
+
+try
+{
+ string current = Environment.CurrentDirectory;
+ WriteInformation($"Current directory: {current}");
+
+ string sourceDirectory = Path.Combine(current, "images");
+ string destinationDirectory = Path.Combine(current, "extracted");
+ string tarFile = Path.Combine(current, "images-archive.tar");
+
+ if (!Directory.Exists(sourceDirectory))
+ {
+ WriteError($"The {sourceDirectory} directory must exist. Please create it and add some files to it.");
+ return;
+ }
+
+ if (File.Exists(tarFile))
+ {
+ // If the Tar archive file already exists then we must delete it.
+ File.Delete(tarFile);
+ WriteWarning($"{tarFile} already existed so it was deleted.");
+ }
+
+ WriteInformation(
+ $"Archiving directory: {sourceDirectory}\n To .tar file: {tarFile}");
+
+ TarFile.CreateFromDirectory(
+ sourceDirectoryName: sourceDirectory,
+ destinationFileName: tarFile,
+ includeBaseDirectory: true);
+
+ WriteInformation($"Does {tarFile} exist? {File.Exists(tarFile)}.");
+
+ if (!Directory.Exists(destinationDirectory))
+ {
+ // If the destination directory does not exist then we must create
+ // it before extracting a Tar archive to it.
+ Directory.CreateDirectory(destinationDirectory);
+ WriteWarning($"{destinationDirectory} did not exist so it was created.");
+ }
+
+ WriteInformation(
+ $"Extracting archive: {tarFile}\n To directory: {destinationDirectory}");
+
+ TarFile.ExtractToDirectory(
+ sourceFileName: tarFile,
+ destinationDirectoryName: destinationDirectory,
+ overwriteFiles: true);
+
+ if (Directory.Exists(destinationDirectory))
+ {
+ foreach (string dir in Directory.GetDirectories(destinationDirectory))
+ {
+ WriteInformation(
+ $"Extracted directory {dir} containing these files: " +
+ string.Join(',', Directory.EnumerateFiles(dir)
+ .Select(file => Path.GetFileName(file))));
+ }
+ }
+}
+catch (Exception ex)
+{
+ WriteError(ex.Message);
+}
diff --git a/vscode/Chapter09/WorkingWithTarArchives/WorkingWithTarArchives.csproj b/vscode/Chapter09/WorkingWithTarArchives/WorkingWithTarArchives.csproj
new file mode 100644
index 0000000..52d7d5a
--- /dev/null
+++ b/vscode/Chapter09/WorkingWithTarArchives/WorkingWithTarArchives.csproj
@@ -0,0 +1,45 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
diff --git a/vscode/Chapter09/WorkingWithTarArchives/images/category1.jpeg b/vscode/Chapter09/WorkingWithTarArchives/images/category1.jpeg
new file mode 100644
index 0000000..3842ade
Binary files /dev/null and b/vscode/Chapter09/WorkingWithTarArchives/images/category1.jpeg differ
diff --git a/vscode/Chapter09/WorkingWithTarArchives/images/category2.jpeg b/vscode/Chapter09/WorkingWithTarArchives/images/category2.jpeg
new file mode 100644
index 0000000..4fea495
Binary files /dev/null and b/vscode/Chapter09/WorkingWithTarArchives/images/category2.jpeg differ
diff --git a/vscode/Chapter09/WorkingWithTarArchives/images/category3.jpeg b/vscode/Chapter09/WorkingWithTarArchives/images/category3.jpeg
new file mode 100644
index 0000000..19890b5
Binary files /dev/null and b/vscode/Chapter09/WorkingWithTarArchives/images/category3.jpeg differ
diff --git a/vscode/Chapter09/WorkingWithTarArchives/images/category4.jpeg b/vscode/Chapter09/WorkingWithTarArchives/images/category4.jpeg
new file mode 100644
index 0000000..5e0f542
Binary files /dev/null and b/vscode/Chapter09/WorkingWithTarArchives/images/category4.jpeg differ
diff --git a/vscode/Chapter09/WorkingWithTarArchives/images/category5.jpeg b/vscode/Chapter09/WorkingWithTarArchives/images/category5.jpeg
new file mode 100644
index 0000000..3a446d1
Binary files /dev/null and b/vscode/Chapter09/WorkingWithTarArchives/images/category5.jpeg differ
diff --git a/vscode/Chapter09/WorkingWithTarArchives/images/category6.jpeg b/vscode/Chapter09/WorkingWithTarArchives/images/category6.jpeg
new file mode 100644
index 0000000..067aa42
Binary files /dev/null and b/vscode/Chapter09/WorkingWithTarArchives/images/category6.jpeg differ
diff --git a/vscode/Chapter09/WorkingWithTarArchives/images/category7.jpeg b/vscode/Chapter09/WorkingWithTarArchives/images/category7.jpeg
new file mode 100644
index 0000000..a9586f1
Binary files /dev/null and b/vscode/Chapter09/WorkingWithTarArchives/images/category7.jpeg differ
diff --git a/vscode/Chapter09/WorkingWithTarArchives/images/category8.jpeg b/vscode/Chapter09/WorkingWithTarArchives/images/category8.jpeg
new file mode 100644
index 0000000..3608eeb
Binary files /dev/null and b/vscode/Chapter09/WorkingWithTarArchives/images/category8.jpeg differ