C# 我们可以用C在FTP服务器上解压文件吗#

C# 我们可以用C在FTP服务器上解压文件吗#,c#,.net,ftp,zip,C#,.net,Ftp,Zip,我是否可以在FTP中提取ZIP文件,并使用C#将提取的文件放在同一位置?这是不可能的 FTP协议中没有用于解压缩服务器上文件的API 不过,除了FTP访问之外,还具有SSH访问也并不少见。如果是这种情况,您可以连接SSH并在服务器上执行unzipshell命令(或类似命令)来解压缩文件。 看 如果需要,您可以使用FTP协议下载提取的文件(但是如果您有SSH访问权限,您也将有SFTP访问权限。然后,使用SFTP而不是FTP) 一些(很少)FTP服务器提供API,使用SITE EXEC命令(或类

我是否可以在FTP中提取ZIP文件,并使用C#将提取的文件放在同一位置?

这是不可能的

FTP协议中没有用于解压缩服务器上文件的API


不过,除了FTP访问之外,还具有SSH访问也并不少见。如果是这种情况,您可以连接SSH并在服务器上执行
unzip
shell命令(或类似命令)来解压缩文件。

如果需要,您可以使用FTP协议下载提取的文件(但是如果您有SSH访问权限,您也将有SFTP访问权限。然后,使用SFTP而不是FTP)


一些(很少)FTP服务器提供API,使用
SITE EXEC
命令(或类似命令)执行任意shell(或其他)命令。但这真的很少见。您可以使用与上面SSH相同的方式使用此API



如果您想在本地下载和解压缩文件,可以在内存中完成,而无需将ZIP文件存储到物理(临时)文件中。例如,请参阅。

通过FTP下载到MemoryStream,然后您可以解压缩,示例显示了如何获取流,只需更改为MemoryStream并解压缩即可。该示例不使用MemoryStream,但若您熟悉streams,那个么修改这两个示例以使其适合您应该很简单

示例来自:

解压流,例如来自:

下面是一个从ftp下载zip文件的工作示例,解压缩该zip文件,然后将压缩文件上载回同一ftp目录

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;
                        }
                    }
                }
            }
        }
    }
}

如果您试图在ftp上传文件后将其解压到位,则需要运行具有适当权限的服务器端脚本,该脚本可以从您的c#应用程序或c#ssh(如前所述)中启动。

这是您的另一个选项,但在内存流中解压后,我必须将其上载到ftp,对吗?事实上,我希望所有这些都在一个ftp请求中完成。您的上传代码仅适用于文本文件+
ContentLength
未与ftp一起使用。嗯,我使用的MSDN示例中使用了ContentLength,因此,如果没有使用它,如您所建议,为什么要使用它?zip文件包含位图而不是文本文件1)甚至MSDN也可能是错误的。2) 这意味着您在上载过程中损坏了位图。@Aaron.S(我没有收到关于您的响应的通知,因为您没有使用
@
)-绝对没有,只需在.zip中测试.jpg即可。它将在上载后损坏。我已经用你的代码进行了测试,没有任何修改。这是可能的,见Aaron。NathanPrather Aaron的答案将ZIP下载到本地计算机,提取单个文件并上传到服务器。这肯定不是大多数人在“FTP服务器中解压文件”中想象的情况因此,不,不可能按照OP的要求去做更不用说答案中的上传代码会破坏任何二进制文件。--这并不意味着他的回答对某些人(比如你)没有用处。
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("========================");
                    }
                }
            }
        }
    }
}
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;
                        }
                    }
                }
            }
        }
    }
}