c# - 异步/等待 ftpupload 损坏上传的文件

标签 c# wpf

我正在尝试使用 async/await 模式 ftpupload 一个 zip 文件:

    private async void button2_Click(object sender, RoutedEventArgs e)
    {

        await processFtp();

    }
    async Task processFtp()
    {
        string result = "";
        string ftpHost = "ftp://mysite/mysubdir";

        string ftpUser = "itsme";

        string ftpPassword = "mypw";

        string ftpfullpath = ftpHost + "/" + "OutdoorTest.zip";

        string fileToUpload = @"c:\temp\Outdoorbilder.zip";
        try
        {

            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpfullpath);
            request.Method = WebRequestMethods.Ftp.UploadFile;

            request.Credentials = new NetworkCredential(ftpUser,ftpPassword);
            request.UseBinary = true;
            request.KeepAlive = false;
            request.ReadWriteTimeout = 1000000;
            request.Timeout = 1000000;

            using (Stream requestStream = request.GetRequestStream())
            {

                using (FileStream fs = File.OpenRead(fileToUpload))
                {
                    byte[] b = new byte[10 * 1024];
                    int readLength = 0;
                    int sentLength = 0;
                    while ((readLength = fs.Read(b, 0, b.Length)) > 0)
                    {
                        await requestStream.WriteAsync(b, 0, b.Length);
                        int percentComplete = (int)((float)(sentLength += readLength) / (float)fs.Length * 100);
                        ftpprogress.Value =  percentComplete;
                    }
                    requestStream.Close();
                    requestStream.Flush();
                }
            }

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            response.Close();


            result = response.StatusDescription;
        }
        catch (WebException e)
        {

            result = e.Message;
            if (e.Status == WebExceptionStatus.ProtocolError)
            {
                result = result + "Status Code : " +
                    ((FtpWebResponse)e.Response).StatusCode;
                result = result + "\nStatus Description : " +
                    ((FtpWebResponse)e.Response).StatusDescription;
            }
        }
        catch (Exception e)
        {
            result = e.Message;
        }


        MessageBox.Show(result);
    }
}

代码似乎运行良好,我收到了 226 响应。但是 ftp 服务器上的 zip 文件比原始文件大 1000 字节左右,下载到移动 android 设备后无法打开/解压缩。

当我在没有异步/等待模式的情况下上传时,上传的文件在 ftp 服务器上的大小与本地原始文件的大小相同。

这是如何/在哪里发生的?

最佳答案

这与 async/await 无关。

您的问题是您没有指定要上传的正确尺寸。看看这两行:

while ((readLength = fs.Read(b, 0, b.Length)) > 0)
{
    await requestStream.WriteAsync(b, 0, b.Length);

您需要指定 WriteAsyc 写入读取量而不是分配给字节缓冲区的量。至少最后一次读取将返回小于缓冲区大小。

所以正确的代码是:

while ((bytesRead = fs.Read(b, 0, b.Length)) > 0)
{
    await requestStream.WriteAsync(b, 0, bytesRead);

关于c# - 异步/等待 ftpupload 损坏上传的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41384629/

相关文章:

c# - 我怎样才能拥有多种身份验证方法而只有一种必须成功?

c# - 数据库恢复后, Entity Framework 有时无法识别过去的迁移

c# - 如何使贝塞尔曲线的单个 anchor 连续或不连续

c# - 将 CheckBox IsChecked 属性绑定(bind)到 ListView 的 SelectedItems 属性

c# - 如何在 BeginInvoke 中进行 Thread.Sleep

来自 c dll 的 c# 回调,指向 c# 类的指针 arg

c# - 为什么 C# WPF 按钮绑定(bind)命令在使用简单注入(inject)器后不会更改 View ?

c# - 找不到方法 : 'Void System.Diagnostics.Tracing.FrameworkEventSource.BeginGetResponse(System.Object, System.String)'

c# - 使用Caliburn Micro Framework将文件拖放到WPF中

c# - DirectShow 库 - 如何使用 directshow 库捕获图像而不在 PictureBox 或面板上显示网络摄像头实时图像