C# 我们可以用C在FTP服务器上解压文件吗#
我是否可以在FTP中提取ZIP文件,并使用C#将提取的文件放在同一位置?这是不可能的 FTP协议中没有用于解压缩服务器上文件的APIC# 我们可以用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访问之外,还具有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;
}
}
}
}
}
}
}