如何将文件从 MemoryStream 上传到 FTP 服务器

How to upload a file from a MemoryStream to an FTP server

我创建了一个简单的应用程序来收集表单数据,在内存中生成 XML 作为 MemoryStream 对象,然后使用 SMB 将 XML 传送到服务器。 SMB送货方式简单:

var outputFile = new FileStream($@"{serverPath}\{filename}.xml", FileMode.Create);
int Length = 256;
Byte[] buffer = new Byte[Length];
int bytesRead = stream.Read(buffer, 0, Length);

while (bytesRead > 0)
{
    outputFile.Write(buffer, 0, bytesRead);
    bytesRead = stream.Read(buffer, 0, Length);
}

但是,我需要使用 FTP(使用凭据)创建替代交付方法。我不想重写我的 XML 方法,因为在内存中创建它可以节省写入磁盘的时间,这在过去一直是我们环境中的一个问题。

我找不到任何示例来解释(对于编码能力非常有限的人)如何完成这样的事情。

通常当我需要将文件上传到 FTP 服务器时,我会使用这样的方法:

using (var client = new WebClient())
{
    client.Credentials = new NetworkCredential("user", "pass");
    client.UploadFile(uri, WebRequestMethods.Ftp.UploadFile, filename.xml);
}

是否可以将其改编为从 MemoryStream 而不是磁盘上的文件上传? 如果没有,还有什么其他方法可以将 MemoryStream 上传到 FTP 服务器?

或者使用 FtpWebRequest, as you can see in :

WebRequest request =
     WebRequest.Create("ftp://ftp.example.com/remote/path/filename.xml");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
using (Stream ftpStream = request.GetRequestStream())
{
    memoryStream.CopyTo(ftpStream);
}

或使用WebClient.OpenWrite(您也可以在@Neptune 的回答中看到):

using (var webClient = new WebClient())
{
    const string url = "ftp://ftp.example.com/remote/path/filename.xml";
    using (Stream uploadStream = client.OpenWrite(url))
    {
        memoryStream.CopyTo(uploadStream);
    }
}

同样,您现有的 FileStream 代码可以简化为:

using (var outputFile = File.Create($@"{serverPath}\{filename}.xml"))
{
    stream.CopyTo(outputFile);
}

虽然显然,更好的办法是避免中间 MemoryStream 并将 XML 直接写入 FileStreamWebRequest.GetRequestStream(使用它们常见的 Stream界面)。

您可以使用方法 OpenWrite/OpenWriteAsync 获取可以从任何来源写入的流(stream/array/...等) 这是一个使用 OpenWriteMemoryStream:

写入的示例
var sourceStream = new MemoryStream();
// Populate your stream with data ...
using (var webClient = new WebClient())
{
     using (Stream uploadStream = client.OpenWrite(uploadUrl))
     {
         sourceStream.CopyTo(uploadStream);
     }
}