-1

I've the below code, that create a new zip file, then add entry to this file with NoCompression i.e. ZERO compression ratio then try to read this entry as normal text.

using System;
using System.IO;
using System.IO.Compression;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            using (FileStream zipToOpen = new FileStream(@"d:\release.zip", FileMode.Create))
            {
                using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create))
                {
                    ZipArchiveEntry readmeEntry = archive.CreateEntry("Readme.txt", CompressionLevel.NoCompression);
                    using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
                    {
                            writer.WriteLine("Information about this package.");
                            writer.WriteLine("========================");
                    }
                }
            }

           string text = System.IO.File.ReadAllText(@"d:\release.zip\Readme.txt");
           Console.WriteLine("Contents of WriteText.txt = {0}", text);
        }
    }
}

Both the zip file and its entry are created, and I can access them from the windows explorer, but once the code try to read it, it get the below error:

Unhandled Exception: System.IO.DirectoryNotFoundException: Could not find a part of the path 'd:\release.zip\Readme.txt'. at System.IO.Win32FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions opti ons, FileStream parent) at System.IO.Win32FileSystem.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions o ptions, FileStream parent) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at System.IO.File.InternalReadAllText(String path, Encoding encoding)
at System.IO.File.ReadAllText(String path) at ConsoleApplication.Program.Main(String[] args)

Nikolay K
  • 3,770
  • 3
  • 25
  • 37
Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203
  • 5
    Um... You can't treat a zip file as a normal directory. The path `d:\release.zip\Readme.txt` is not valid. Just because Explorer takes extra steps to let you browse there and read a text file doesn't make it an actual path. Don't believe me? Open a command prompt and type `dir d:\release.zip\Readme.txt` and see what happens. Adding the file to the zip with no compression simply means your zip file isn't as small as it could be because you've added non-compressed content to it. – Ken White Dec 10 '16 at 07:48

1 Answers1

4

Firstly it should be noted that you did not create a zip file, you created an archive file with a specific compression; in your case, you created a ZIP archive with no compression.

and I can access them from the windows explorer

I can't because I have 7zip associated with .zip files, so 7z opens the archive; in your case Windows Explorer is doing this for you. So when you browse to the .zip file and open it, Explorer treats the archive file as a folder and shows you the contents of the archive.

However, when you do this:

string text = System.IO.File.ReadAllText(@"d:\release.zip\Readme.txt");

System.IO.File.ReadAllText will open the specific file you pass as the parameter, which in your case is d:\release.zip\Readme.txt. So the path attempting to be opened is: drive D:, folder release.zip, file Readme.txt ... since d:\release.zip is a file and not a folder, the path cannot be found, which is why you are getting the DirectoryNotFoundException exception.

To this, if you want to read the entry, just do what you did to Create the archive, except Read from the Open'ed archive and .GetEntry instead of .CreateEntry, example:

string text = string.Empty;
using (FileStream zipToOpen = new FileStream(@"c:\test\release.zip", FileMode.Open)) {
    using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Read)) {
        ZipArchiveEntry readmeEntry = archive.GetEntry("Readme.txt");
        using (StreamReader reader = new StreamReader(readmeEntry.Open())) {
            text = reader.ReadToEnd();
        }
    }
}
Console.WriteLine("Contents of WriteText.txt = {0}", text);

Hope that can help.

txtechhelp
  • 6,625
  • 1
  • 30
  • 39