Downloading zip file from sftp error with .NET and C#

63 Views Asked by At

I am trying to use SshNet to access a sftp folder and then access the contents in a zip file located there. I am getting the following exception:

System.IO.InvalidDataException: 'Central Directory corrupt'

Inner Exception:
EndOfStreamException: Unable to read beyond the end of the stream

Here is my function I'm using:

public string GetContents(string filename, ref string error)
{
    string contents = "";

    using (var sftp = new SftpClient(SFTP_URI, SFTP_USERNAME, SFTP_PASSWORD))
    {
        try
        {
            sftp.Connect();
        }
        catch (Exception exc)
        {
            error = "Unable to connect " + SFTP_USERNAME + "@" + SFTP_URI + " - " + exc.Message;
            return contents;
        }

        if (!sftp.Exists(filename))
        {
            error = "Filename doesn't exist - " + filename;
            return contents;
        }

        using (Stream stream = sftp.OpenRead(filename))
        {
            using (var archive = new ZipArchive(stream, ZipArchiveMode.Read, true)) //exception thrown here
            {
                foreach (var files in archive.Entries) //just using this block for testing to see if I can access the zip folder
                {
                    Console.WriteLine(files);
                }
            }
        }
    }

    return contents;
}
1

There are 1 best solutions below

0
Saif On

Chris Schaller's comment made me think to first read that zip directory into the MemoryStream object and then pass that to the ZipArchive constructor. That worked!

public string GetContents(string filename, ref string error)
{
    string contents = "";
    using (var sftp = new SftpClient(SFTP_URI, SFTP_USERNAME, SFTP_PASSWORD))
    {
        try
        {
            sftp.Connect();
        }
        catch (Exception exc)
        {
            error = "Unable to connect " + SFTP_USERNAME + "@" + SFTP_URI + " - " + exc.Message;
            return contents;
        }

        if (!sftp.Exists(filename))
        {
            error = "Filename doesn't exist - " + filename;
            return contents;
        }

        using (MemoryStream ms = new MemoryStream())
        {
            try
            {
                sftp.DownloadFile(filename, ms);
                using (var archive = new ZipArchive(ms, ZipArchiveMode.Read, true))
                {
                    foreach (var files in archive.Entries)
                    {
                        using (var zipEntrySteam = new StreamReader( files.Open()))
                        {
                            Console.WriteLine(zipEntrySteam.ReadToEnd());//just for testing.
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                error = "Exception downloading " + filename + " - " + exc.Message;
                return contents;
            }
        }
    }
    return contents;
}