我正在尝试使用async / await模式ftpupload一个zipfile:
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字节,并且下载到移动设备后无法打开/提取。
当我上传没有async / await模式时,上传的文件在ftp服务器上的大小与本地原始文件大小相同。
这种情况如何/在何处发生?
答案 0 :(得分:3)
这与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);