Quantum_Kernel
Quantum_Kernel

Reputation: 333

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

I created a simple application that collects form data, generates an XML in memory as a MemoryStream object, and and delivers the XML to a server using SMB. The delivery method is simple for 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);
}

However, I need to create an alternative delivery method using FTP (with credentials). I don't want to rewrite my XML method, as creating it in memory saves writing to disk which has been a problem in our environment in the past.

I have not been able to find any examples that explain (for a person of very limited coding ability) how such a thing may be accomplished.

Generally when I have need to upload a file to an FTP server, I use something like this:

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

Can this be adapted to upload from a MemoryStream instead of a file on disk? If not, what other way could I upload a MemoryStream to an FTP server?

Upvotes: 2

Views: 6311

Answers (2)

Martin Prikryl
Martin Prikryl

Reputation: 202088

Either use FtpWebRequest, as you can see in Upload a streamable in-memory document (.docx) to FTP with C#?:

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

or use WebClient.OpenWrite (as you can also see in the answer by @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);
    }
}

Equivalently, your existing FileStream code can be simplified to:

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

Though obviously, even better would be to avoid the intermediate MemoryStream and write the XML directly to FileStream and WebRequest.GetRequestStream (using their common Stream interface).

Upvotes: 4

Mohammad
Mohammad

Reputation: 1990

You can use the methods OpenWrite/OpenWriteAsync to get a stream that you can write to from any source (stream/array/...etc.) Here is an example using OpenWrite to write from a MemoryStream:

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

Upvotes: 1

Related Questions