Can we unzip file in FTP server using C#

2020-02-12 04:18发布

问题:

Can I extract the ZIP file in FTP and place this extracted file on the same location using C#?

回答1:

It's not possible.

There's no API in the FTP protocol to un-ZIP a file on a server.


Though, it's not uncommon that one, in addition to an FTP access, have also an SSH access. If that's the case, you can connect with the SSH and execute the unzip shell command (or similar) on the server to decompress the files.
See C# send a simple SSH command.

If you need, you can then download the extracted files using the FTP protocol (Though if you have the SSH access, you will also have an SFTP access. Then, use the SFTP instead of the FTP.).


Some (very few) FTP servers offer an API to execute an arbitrary shell (or other) commands using the SITE EXEC command (or similar). But that's really very rare. You can use this API the same way as the SSH above.



回答2:

Download via FTP to MemoryStream, then you can unzip, example shows how to get stream, just change to MemoryStream and unzip. Example doesn't use MemoryStream but if you are familiar with streams it should be trivial to modify these two examples to work for you.

example from: https://docs.microsoft.com/en-us/dotnet/framework/network-programming/how-to-download-files-with-ftp

using System;  
using System.IO;  
using System.Net;  
using System.Text;  

namespace Examples.System.Net  
{  
    public class WebRequestGetExample  
    {  
        public static void Main ()  
        {  
            // Get the object used to communicate with the server.  
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");  
            request.Method = WebRequestMethods.Ftp.DownloadFile;  

            // This example assumes the FTP site uses anonymous logon.  
            request.Credentials = new NetworkCredential ("anonymous","janeDoe@contoso.com");  

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();  

            Stream responseStream = response.GetResponseStream();  
            StreamReader reader = new StreamReader(responseStream);  
            Console.WriteLine(reader.ReadToEnd());  

            Console.WriteLine("Download Complete, status {0}", response.StatusDescription);  

            reader.Close();  
            response.Close();    
        }  
    }  
}

decompress stream, example from: https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-compress-and-extract-files

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

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

here is a working example of downloading zip file from ftp, decompressing that zip file and then uploading the compressed files back to the same ftp directory

using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string location = @"ftp://localhost";
            byte[] buffer = null;

            using (MemoryStream ms = new MemoryStream())
            {
                FtpWebRequest fwrDownload = (FtpWebRequest)WebRequest.Create($"{location}/test.zip");
                fwrDownload.Method = WebRequestMethods.Ftp.DownloadFile;
                fwrDownload.Credentials = new NetworkCredential("anonymous", "janeDoe@contoso.com");

                using (FtpWebResponse response = (FtpWebResponse)fwrDownload.GetResponse())
                using (Stream stream = response.GetResponseStream())
                {
                    //zipped data stream
                    //https://stackoverflow.com/a/4924357
                    byte[] buf = new byte[1024];
                    int byteCount;
                    do
                    {
                        byteCount = stream.Read(buf, 0, buf.Length);
                        ms.Write(buf, 0, byteCount);
                    } while (byteCount > 0);
                    //ms.Seek(0, SeekOrigin.Begin);
                    buffer = ms.ToArray();
                }
            }

            //include System.IO.Compression AND System.IO.Compression.FileSystem assemblies
            using (MemoryStream ms = new MemoryStream(buffer))
            using (ZipArchive archive = new ZipArchive(ms, ZipArchiveMode.Update))
            {
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    FtpWebRequest fwrUpload = (FtpWebRequest)WebRequest.Create($"{location}/{entry.FullName}");
                    fwrUpload.Method = WebRequestMethods.Ftp.UploadFile;
                    fwrUpload.Credentials = new NetworkCredential("anonymous", "janeDoe@contoso.com");

                    byte[] fileContents = null;
                    using (StreamReader sr = new StreamReader(entry.Open()))
                    {
                        fileContents = Encoding.UTF8.GetBytes(sr.ReadToEnd());
                    }

                    if (fileContents != null)
                    {
                        fwrUpload.ContentLength = fileContents.Length;

                        try
                        {
                            using (Stream requestStream = fwrUpload.GetRequestStream())
                            {
                                requestStream.Write(fileContents, 0, fileContents.Length);
                            }
                        }
                        catch(WebException e)
                        {
                            string status = ((FtpWebResponse)e.Response).StatusDescription;
                        }
                    }
                }
            }
        }
    }
}


回答3:

If you're trying to unzip the files in place after they have been ftp uploaded, you will need to run a server side script with proper permissions that can be fired from within your c# application, or c# ssh as already described earlier.



标签: c# .net ftp zip