Upload a streamable in-memory document (.docx) to

2020-04-01 01:04发布

问题:

I am trying to upload a .docx file which is in MemoryStream to FTP

But when upload is completed, the file is empty.

MemoryStream mms = new MemoryStream();
document2.SaveToStream(mms, Spire.Doc.FileFormat.Docx);

string ftpAddress = "example";
string username = "example";
string password = "example";

using (StreamReader stream = new StreamReader(mms))
{
    // adnu is a random file name.
    WebRequest request =
        WebRequest.Create("ftp://" + ftpAddress + "/public_html/b/" + adnu + ".docx");
    request.Method = WebRequestMethods.Ftp.UploadFile;
    request.Credentials = new NetworkCredential(username, password);
    Stream reqStream = request.GetRequestStream();
    reqStream.Close();
}

回答1:

Write the document directly to the request stream. There's no point using an intermediate MemoryStream. And StreamReader/StreamWriter are for working with text files, while a .docx is a binary file format, so do not use those either.

WebRequest request = WebRequest.Create("ftp://ftp.example.com/remote/path/document.docx");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
using (Stream ftpStream = request.GetRequestStream())
{
    document2.SaveToStream(ftpStream, Spire.Doc.FileFormat.Docx);
}

Or use WebClient.OpenWrite:

using (var webClient = new WebClient())
{
    const string url = "ftp://ftp.example.com/remote/path/document.docx";
    using (Stream uploadStream = client.OpenWrite(url))
    {
        document2.SaveToStream(uploadStream, Spire.Doc.FileFormat.Docx);
    }
}

You will only need an intermediate MemoryStream, if the Spire library requires a seekable stream, what the Stream returned by FtpWebRequest.GetRequestStream is not. I cannot test that.

If that's the case, use:

MemoryStream memoryStream = new MemoryStream();
document2.SaveToStream(memoryStream, Spire.Doc.FileFormat.Docx);

memoryStream.Seek(0, SeekOrigin.Begin);

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

Or again, you can use WebClient.OpenWrite as in the previous example.

See also a similar question Zip a directory and upload to FTP server without saving the .zip file locally in C#.