Загрузить потоковый документ в памяти (.docx) на FTP с помощью С#?

Я пытаюсь загрузить файл .docx, который находится в MemoryStream, на FTP

Но когда загрузка завершена, файл пуст.

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

person Ediz Nezir    schedule 26.11.2017    source источник
comment
вы не пишете в поток запросов?   -  person Dennis Kuypers    schedule 26.11.2017
comment
Просто следуйте примеру в MSDN   -  person Filburt    schedule 26.11.2017
comment
Я пытался, но это не работает для меня. Результаты повреждены или пустые файлы   -  person Ediz Nezir    schedule 26.11.2017
comment
Вы используете StreamReader вместо StreamWriter. Вы никогда ничего не пишете в WebRequest.   -  person Camilo Terevinto    schedule 26.11.2017
comment
Я заменил StreamReader на StreamWriter, но он все еще не работает. Я новичок в С#, и я не могу решить эту проблему.   -  person Ediz Nezir    schedule 26.11.2017


Ответы (1)


Запишите документ непосредственно в поток запросов. Нет смысла использовать промежуточный MemoryStream. И StreamReader/StreamWriter предназначены для работы с текстовыми файлами, а .docx — это двоичный формат файла, поэтому их тоже не используйте.

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

Или используйте 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);
    }
}

Вам понадобится только промежуточный MemoryStream, если библиотеке Spire требуется поток с возможностью поиска, а Stream, возвращаемый FtpWebRequest.GetRequestStream, не является. Я не могу это проверить.

Если это так, используйте:

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

Или, опять же, вы можете использовать WebClient.OpenWrite, как в предыдущем примере.

См. также аналогичный вопрос Заархивируйте каталог и загрузите его на FTP-сервер, не сохраняя ZIP-файл локально на C#.

person Martin Prikryl    schedule 26.11.2017