我用C#实现FTP功能,已经可以上传下载了,但是有不稳定,当远程FTP服务器的数据量大或网速慢的时候下一会儿就提示如下错误:
1、“基础连接断开,超时”,
2、用户代码未处理 System.Net.WebException Message="远程服务器返回错误: (500) 语法错 误,无法识别命令。"
请问用API是不是要稳定点,我的下载代码如下:
BackgroundWorker bw = sender as BackgroundWorker;
FtpSettings f = e.Argument as FtpSettings;IList<string> vDownFiles =new List<string>();
string[] temp = GetFileList(f.Host ,f.Port , f.Username , f.Password ,f.TargetFolder , "*.*");
for (int i = 0; i < temp.Length; i++)
{
vDownFiles.Add(temp[i]);
}foreach (string item in vDownFiles)
{
if (item.Contains("win2003Hp.iso"))
{
int kk = 10;
} FileStream outputStream = new FileStream(@"e:\test\" + item, FileMode.Create); // set up the host string to request. this includes the target folder and the target file name (based on the source filename)
string DownLoadPath = String.Format("{0}/{1}{2}", f.Host, f.TargetFolder == "" ? "" : f.TargetFolder + "/", Path.GetFileName(item));
if (!DownLoadPath.ToLower().StartsWith("ftp://"))
DownLoadPath = "ftp://" + DownLoadPath;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(DownLoadPath);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.UseBinary = true;
request.UsePassive = f.Passive;
request.Credentials = new NetworkCredential(f.Username, f.Password); FtpWebResponse response = (FtpWebResponse)request.GetResponse(); Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
string FileSizeDescription = GetFileSize(cl);
//int bufferSize = 2048;
int readCount;
long DownLoadBytes = 0;
int ChunkSize = 4096, NumRetries = 0, MaxRetries = 50;
byte[] buffer = new byte[ChunkSize]; readCount = ftpStream.Read(buffer, 0, ChunkSize);
while (readCount > 0)
{ //outputStream.Write(buffer, 0, readCount);
//readCount = ftpStream.Read(buffer, 0, bufferSize); //DownLoadBytes += readCount; //// update the user interface
//string SummaryText = String.Format("传输完成比率 {0} / {1}", GetFileSize(DownLoadBytes), FileSizeDescription);
//bw.ReportProgress((int)(((decimal)DownLoadBytes / (decimal)cl ) * 100), SummaryText);
try
{
if (bw.CancellationPending)
return; // send this chunk to the server. it is sent as a byte[] parameter, but the client and server have been configured to encode byte[] using MTOM.
outputStream.Write(buffer, 0, readCount); // sentBytes is only updated AFTER a successful send of the bytes. so it would be possible to build in 'retry' code, to resume the upload from the current SentBytes position if AppendChunk fails.
DownLoadBytes += readCount; // update the user interface
string SummaryText = String.Format("传输完成比率 {0} / {1}", GetFileSize(DownLoadBytes), FileSizeDescription);
bw.ReportProgress((int)(((double)DownLoadBytes / (double)cl) * 100), SummaryText);
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.ToString());
if (NumRetries++ < MaxRetries)
{
// rewind the filestream and keep trying
ftpStream.Position -= DownLoadBytes;
}
else
{
throw new Exception(String.Format("Error occurred during upload, too many retries. \n{0}", ex.ToString()));
}
}
readCount = ftpStream.Read(buffer, 0, ChunkSize); // read the next chunk (if it exists) into the buffer. the while loop will terminate if there is nothing left to read } ftpStream.Close();
outputStream.Close();
response.Close();
using (FtpWebResponse responseN = (FtpWebResponse)request.GetResponse())
System.Diagnostics.Debug.WriteLine(String.Format("DownLoad File Complete, status {0}", responseN.StatusDescription));}
1、“基础连接断开,超时”,
2、用户代码未处理 System.Net.WebException Message="远程服务器返回错误: (500) 语法错 误,无法识别命令。"
请问用API是不是要稳定点,我的下载代码如下:
BackgroundWorker bw = sender as BackgroundWorker;
FtpSettings f = e.Argument as FtpSettings;IList<string> vDownFiles =new List<string>();
string[] temp = GetFileList(f.Host ,f.Port , f.Username , f.Password ,f.TargetFolder , "*.*");
for (int i = 0; i < temp.Length; i++)
{
vDownFiles.Add(temp[i]);
}foreach (string item in vDownFiles)
{
if (item.Contains("win2003Hp.iso"))
{
int kk = 10;
} FileStream outputStream = new FileStream(@"e:\test\" + item, FileMode.Create); // set up the host string to request. this includes the target folder and the target file name (based on the source filename)
string DownLoadPath = String.Format("{0}/{1}{2}", f.Host, f.TargetFolder == "" ? "" : f.TargetFolder + "/", Path.GetFileName(item));
if (!DownLoadPath.ToLower().StartsWith("ftp://"))
DownLoadPath = "ftp://" + DownLoadPath;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(DownLoadPath);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.UseBinary = true;
request.UsePassive = f.Passive;
request.Credentials = new NetworkCredential(f.Username, f.Password); FtpWebResponse response = (FtpWebResponse)request.GetResponse(); Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
string FileSizeDescription = GetFileSize(cl);
//int bufferSize = 2048;
int readCount;
long DownLoadBytes = 0;
int ChunkSize = 4096, NumRetries = 0, MaxRetries = 50;
byte[] buffer = new byte[ChunkSize]; readCount = ftpStream.Read(buffer, 0, ChunkSize);
while (readCount > 0)
{ //outputStream.Write(buffer, 0, readCount);
//readCount = ftpStream.Read(buffer, 0, bufferSize); //DownLoadBytes += readCount; //// update the user interface
//string SummaryText = String.Format("传输完成比率 {0} / {1}", GetFileSize(DownLoadBytes), FileSizeDescription);
//bw.ReportProgress((int)(((decimal)DownLoadBytes / (decimal)cl ) * 100), SummaryText);
try
{
if (bw.CancellationPending)
return; // send this chunk to the server. it is sent as a byte[] parameter, but the client and server have been configured to encode byte[] using MTOM.
outputStream.Write(buffer, 0, readCount); // sentBytes is only updated AFTER a successful send of the bytes. so it would be possible to build in 'retry' code, to resume the upload from the current SentBytes position if AppendChunk fails.
DownLoadBytes += readCount; // update the user interface
string SummaryText = String.Format("传输完成比率 {0} / {1}", GetFileSize(DownLoadBytes), FileSizeDescription);
bw.ReportProgress((int)(((double)DownLoadBytes / (double)cl) * 100), SummaryText);
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.ToString());
if (NumRetries++ < MaxRetries)
{
// rewind the filestream and keep trying
ftpStream.Position -= DownLoadBytes;
}
else
{
throw new Exception(String.Format("Error occurred during upload, too many retries. \n{0}", ex.ToString()));
}
}
readCount = ftpStream.Read(buffer, 0, ChunkSize); // read the next chunk (if it exists) into the buffer. the while loop will terminate if there is nothing left to read } ftpStream.Close();
outputStream.Close();
response.Close();
using (FtpWebResponse responseN = (FtpWebResponse)request.GetResponse())
System.Diagnostics.Debug.WriteLine(String.Format("DownLoad File Complete, status {0}", responseN.StatusDescription));}
解决方案 »
- winform能全屏无边框显示数据到46寸电视吗,效果要像ppt2007
- c#中二维数组是怎么查找的
- 求助一个c++ 调用C#的多个.cs类的问题,多谢!
- webbrowser控件编程中如何得到iframe 元素本身在 webbrowser 中的坐标?
- DataRow 怎么添加到顶部 就是一行数据出现到上面呢?
- 求解:输入字符串的格式不正确。
- .NET 使用iframe部分页面无法及时更新?
- DataGridView记录如何移动?
- 请高手帮个忙!一个Winfrom中插入的问题!急!急!在线等!
- c#中http的GET请求,请求数据之前要登录才能得到数据,为什么我一直得到的是未登录状态
- Linq问题他求教
- zlib库中uncompress函数在C#中的调用
Stream ftpStream = response.GetResponseStream();
这两句放到try里面去
internal static bool FtpDownloadFile(FtpSite ftpSite) //定义个对象,封装参数
{
if (ftpSite == null)
{
throw new ArgumentNullException("ftpSite");
}
//根据URI创建FtpWebRequest对象
FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(ftp.FileUri);
//ftp用户名和密码
ftpRequest.Credentials = new NetworkCredential(ftpSite.UserName, ftpSite.Password);
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; //指定操作类别
ftpRequest.UseBinary = true; //指定数据传输类型
ftpRequest.KeepAlive = false; //下载完后不用保持连接
return SaveAsFile(ftpRequest, upgradeReport.SaveFileName);
} /// <summary>
/// 将服务端响应流保存至文件
/// </summary>
static bool SaveAsFile(WebRequest request, string saveName)
{
WebResponse response = null;
request.Proxy = null;
request.Timeout = 60000; //设置请求超时时间
//request.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
try
{
response = (WebResponse)request.GetResponse();
using (var responseStream = response.GetResponseStream())
{
using (var fs = new FileStream(saveName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
{
int bufferLength = 2048, offset = 0;
byte[] buffer = new byte[bufferLength];
while ((offset = responseStream.Read(buffer, 0, bufferLength)) > 0)
{
fs.Write(buffer, 0, offset);
}
}
}
return true;
}
catch (Exception exp)
{
//handle exp or throw;
return false;
}
finally
{
if (response != null) response.Close();
}
}
FileStream outputStream = new FileStream(@"e:\test\" + item, FileMode.Create); // set up the host string to request. this includes the target folder and the target file name (based on the source filename)
string DownLoadPath = String.Format("{0}/{1}{2}", f.Host, f.TargetFolder == "" ? "" : f.TargetFolder + "/", Path.GetFileName(item));
if (!DownLoadPath.ToLower().StartsWith("ftp://"))
DownLoadPath = "ftp://" + DownLoadPath;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(DownLoadPath);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.UseBinary = true;
request.UsePassive = f.Passive;
request.Credentials = new NetworkCredential(f.Username, f.Password);
request.KeepAlive = true;
request.ReadWriteTimeout = System.Threading.Timeout.Infinite;
request.Timeout = System.Threading.Timeout.Infinite;
request.Proxy = null;
request.UsePassive = false; FtpWebResponse response = (FtpWebResponse)request.GetResponse(); Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
string FileSizeDescription = GetFileSize(cl);
//int bufferSize = 2048;
int readCount;
long DownLoadBytes = 0;
int ChunkSize = 4096, NumRetries = 0, MaxRetries = 50;
byte[] buffer = new byte[ChunkSize]; readCount = ftpStream.Read(buffer, 0, ChunkSize);
while (readCount > 0)
{ //outputStream.Write(buffer, 0, readCount);
//readCount = ftpStream.Read(buffer, 0, bufferSize); //DownLoadBytes += readCount; //// update the user interface
//string SummaryText = String.Format("传输完成比率 {0} / {1}", GetFileSize(DownLoadBytes), FileSizeDescription);
//bw.ReportProgress((int)(((decimal)DownLoadBytes / (decimal)cl ) * 100), SummaryText);
try
{
if (bw.CancellationPending)
return; // send this chunk to the server. it is sent as a byte[] parameter, but the client and server have been configured to encode byte[] using MTOM.
outputStream.Write(buffer, 0, readCount); // sentBytes is only updated AFTER a successful send of the bytes. so it would be possible to build in 'retry' code, to resume the upload from the current SentBytes position if AppendChunk fails.
DownLoadBytes += readCount; // update the user interface
string SummaryText = String.Format("传输完成比率 {0} / {1}", GetFileSize(DownLoadBytes), FileSizeDescription);
bw.ReportProgress((int)(((double)DownLoadBytes / (double)cl) * 100), SummaryText);
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.ToString());
if (NumRetries++ < MaxRetries)
{
// rewind the filestream and keep trying
ftpStream.Position -= DownLoadBytes;
}
else
{
throw new Exception(String.Format("Error occurred during upload, too many retries. \n{0}", ex.ToString()));
}
}
readCount = ftpStream.Read(buffer, 0, ChunkSize); // read the next chunk (if it exists) into the buffer. the while loop will terminate if there is nothing left to read } ftpStream.Close();
outputStream.Close();
response.Close();
using (FtpWebResponse responseN = (FtpWebResponse)request.GetResponse())
System.Diagnostics.Debug.WriteLine(String.Format("DownLoad File Complete, status {0}", responseN.StatusDescription)); }
/// 下载
/// </summary>
/// <param name="filePath"></param>
/// <param name="fileName"></param>
public void Download(string ftpURI, string fPath, string ftpUserID, string ftpPassword, string filePath)
{
this.toolStripProgressBar1.Value = 0;
using (BackgroundWorker backgroundWorker = new BackgroundWorker())
{
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.WorkerSupportsCancellation = true;
// 异步获取数据
backgroundWorker.DoWork += new DoWorkEventHandler(delegate(object o, DoWorkEventArgs workerEventArgs)
{
string[] temp = GetFileList(ftpURI, 21, ftpUserID, ftpPassword, fPath, "*.*"); foreach (string item in temp)
{
string fileName = item; ifComplete = false; this.BeginInvoke(new myDelegatDoProcess(doProcess)); //backgroundWorker.ReportProgress((int)(((double)0.1 / (double)1) * 100), "正在获得文件列表,请稍候..."); System.Threading.Thread.Sleep(1000); FtpWebRequest reqFTP;
try
{
//backgroundWorker.ReportProgress((int)(((double)0.75 / (double)1) * 100), "正在下载文件,请稍候..."); System.Threading.Thread.Sleep(1000); FileStream outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create); reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("Ftp://" + ftpURI + "/" + fPath + "/" + fileName));
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.UsePassive = false;
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
long cl = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[bufferSize];
long DownLoadBytes = 0;
string FileSizeDescription = GetFileSize(cl);
readCount = ftpStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
outputStream.Write(buffer, 0, readCount);
readCount = ftpStream.Read(buffer, 0, bufferSize); DownLoadBytes += readCount;
//this.Text = "文件[" + fileName + "]下载完成" + GetFileSize(DownLoadBytes) + @"/" + FileSizeDescription;
//this.Refresh();
string SummaryText = String.Format("正在下载文件 {0} 传输完成比率 {1} / {2}",item , GetFileSize(DownLoadBytes), FileSizeDescription);
backgroundWorker.ReportProgress((int)(((double)DownLoadBytes / (double)cl) * 100), SummaryText);
//this.Refresh();
//statusStrip1.Refresh();
} ftpStream.Close();
outputStream.Close();
response.Close();
}
catch (Exception ex)
{
//Insert_Standard_ErrorLog.Insert("FtpWeb", "Download Error --> " + ex.Message);
}
}
}); backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(delegate(object sender, ProgressChangedEventArgs e)
{
//if (e.UserState != null && e.UserState.ToString() != "") { m_Result = e.UserState.ToString(); }
this.toolStripStatusLabel1.Text = e.UserState.ToString(); // the message will be something like: 45 Kb / 102.12 Mb
try
{
this.toolStripProgressBar1.Value = Math.Min(this.toolStripProgressBar1.Maximum, e.ProgressPercentage);
}
catch { }
this.statusStrip1.Refresh();
}); backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs x)
{
string SummaryText = String.Format("下载完成");
backgroundWorker.ReportProgress((int)(1), SummaryText);
}); backgroundWorker.RunWorkerAsync();
}
}
调用方法:
string vFtpUrl = "yiduoi001.gicp.net";
string vUserID = "ecff";
string vPassWord = "ecSffn";
string vPath = "ecDownload";
Download(vFtpUrl, vPath, vUserID, vPassWord, @"e:\test\qqbb");