загрузка ftp слишком велика - PullRequest
2 голосов
/ 13 декабря 2011

Я написал функцию в C # для загрузки файла, когда копирование в общую папку не работает.Я заметил, что любые загруженные файлы имеют размер примерно в 1,5-2 раза больше исходного и являются недопустимыми.Вот код:

public bool save_FTPUpload(FileInfo fi_attachment)
{
    bool fileSaved = false;
    string filename = fi_attachment.Name;

    while (!fileSaved)
    {
        string file_ftpURI = string.Format("{0}/{1}", ftpURI, filename);
        FtpWebRequest file_exist_request = (FtpWebRequest)FtpWebRequest.Create(file_ftpURI);
        file_exist_request.Credentials = new NetworkCredential(ftp_user, ftp_pass);
        file_exist_request.Method = WebRequestMethods.Ftp.GetFileSize;
        try
        {
            FtpWebResponse response = (FtpWebResponse)file_exist_request.GetResponse();
        }
        catch (WebException ex)
        {
            FtpWebResponse response = (FtpWebResponse)ex.Response;
            if (response.StatusCode ==
                FtpStatusCode.ActionNotTakenFileUnavailable)
            {
                FtpWebRequest upload_request = (FtpWebRequest)FtpWebRequest.Create(file_ftpURI);
                upload_request.Credentials = new NetworkCredential(ftp_user, ftp_pass);

                upload_request.Method = WebRequestMethods.Ftp.UploadFile;
                upload_request.UsePassive = true;
                upload_request.UseBinary = true;
                upload_request.KeepAlive = false;

                StreamReader attachment = new StreamReader(fi_attachment.FullName);
                byte[] attachmentData = Encoding.UTF8.GetBytes(attachment.ReadToEnd());
                upload_request.ContentLength = attachmentData.Length;

                //Stream upload_request_stream = upload_request.GetRequestStream();
                using (Stream upload_request_stream = upload_request.GetRequestStream())
                {
                    upload_request_stream.Write(attachmentData, 0, attachmentData.Length);
                    upload_request_stream.Close();
                }
                FtpWebResponse upload_response = (FtpWebResponse)upload_request.GetResponse();

                fileSaved = true;
            }
        }
    }
    return fileSaved;
}

Любая помощь в выяснении этого будет отличной.

Ответы [ 2 ]

7 голосов
/ 13 декабря 2011

Вам необходимо скопировать содержимое файла в двоичном режиме, например:

var response = (FtpWebResponse)ex.Response;
if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable) {
    FtpWebRequest upload_request = (FtpWebRequest)FtpWebRequest.Create(file_ftpURI);
    upload_request.Credentials = new NetworkCredential(ftp_user, ftp_pass);
    upload_request.Method = WebRequestMethods.Ftp.UploadFile;
    upload_request.UsePassive = true;
    upload_request.UseBinary = true;
    upload_request.KeepAlive = false;
    var attachment = File.Open(fi_attachment.FullName, FileMode.Open);
    using (Stream upload_request_stream = upload_request.GetRequestStream()) {
        attachment.CopyTo(upload_request_stream);
        upload_request_stream.Close();
    }
    var upload_response = (FtpWebResponse)upload_request.GetResponse();
    fileSaved = true;
}

Ваша текущая программа читает ее как очень длинную строку в кодировке UTF-8, которая, вероятно, учитывает изменение размера файла.

2 голосов
/ 13 декабря 2011

Почему весь этот танец декодирует файл, а затем перекодирует его?У вас есть два потока, верно?Вы хотите, чтобы на сервере существовал тот же файл, который имеется на диске?Stream.CopyTo будет значительно менее подвержен ошибкам.

Вы можете заменить

                StreamReader attachment = new StreamReader(fi_attachment.FullName);
                byte[] attachmentData = Encoding.UTF8.GetBytes(attachment.ReadToEnd());
                upload_request.ContentLength = attachmentData.Length;

                //Stream upload_request_stream = upload_request.GetRequestStream();
                using (Stream upload_request_stream = upload_request.GetRequestStream())
                {
                    upload_request_stream.Write(attachmentData, 0, attachmentData.Length);
                    upload_request_stream.Close();
                }

на (с макушки головы)

using (var fs = File.OpenRead(fi_attachment.FullName))
using (Stream upload_request_stream = upload_request.GetRequestStream())
{
    fs.CopyTo(upload_request_stream);
}
...