当.NET中的FTP服务器上的命令失败时会发生什么?
我有这个源代码:当.NET中的FTP服务器上的命令失败时会发生什么?
public static void FTP_SERVER()
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/");
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential("myusername", "mypassword");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
ArrayList directories = new ArrayList();
while (!reader.EndOfStream)
{
String directory = reader.ReadLine();
int i = 0;
for (i = 0; i < directories.Count && Convert.ToInt32(directory) > Convert.ToInt32(directories[i] + ""); i++);
directories.Insert(i, directory);
}
String[] agents = Crawler.CrawlerDbUtils.getAllAgentIDs();
reader.Close();
response.Close();
int j = 0;
for (int i = 0; i < directories.Count; i++)
{
try
{
while ((j < agents.Length) && (Convert.ToInt32(agents[j]) < Convert.ToInt32(directories[i] + "")))
{
try
{
request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + agents[j]);
request.Method = WebRequestMethods.Ftp.MakeDirectory;
request.Credentials = new NetworkCredential("myusername", "mypassword");
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
response.Close();
}
catch (Exception exception)
{ }
j++;
}
if (Convert.ToInt32(agents[j]) == Convert.ToInt32(directories[i] + ""))
{
request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/");
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential("myusername", "mypassword");
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
reader = new StreamReader(responseStream);
ArrayList files = new ArrayList();
while (!reader.EndOfStream)
{
String file = reader.ReadLine();
int q = 0;
for (q = 0; q < files.Count && file.CompareTo(files[q] + "") > 0; q++) ;
files.Insert(q, file);
}
reader.Close();
response.Close();
String[] dbFiles = Crawler.CrawlerDbUtils.getAllPictures(directories[i] + "");
int r = 0;
for (int q = 0; q < files.Count; q++)
{
while ((r < dbFiles.Length) && ((dbFiles[r] + "").CompareTo(files[q] + "") < 0))
{
r++;
}
try
{
if ((r >= dbFiles.Length) || ((dbFiles[r] + "").Equals(files[q]) == false))
{
request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/" + files[q]);
request.Method = WebRequestMethods.Ftp.DeleteFile;
request.Credentials = new NetworkCredential("myusername", "mypassword");
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
response.Close();
}
}
catch (Exception exception)
{ }
}
j++;
}
else
{
request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/");
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential("myusername", "mypassword");
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
reader = new StreamReader(responseStream);
ArrayList files = new ArrayList();
while (!reader.EndOfStream)
{
files.Add(reader.ReadLine());
}
reader.Close();
response.Close();
for (int k = 0; k < files.Count; k++)
{
request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/" + files[k]);
request.Method = WebRequestMethods.Ftp.DeleteFile;
request.Credentials = new NetworkCredential("myusername", "mypassword");
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
response.Close();
}
request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + directories[i] + "/");
request.Method = WebRequestMethods.Ftp.RemoveDirectory;
request.Credentials = new NetworkCredential("myusername", "mypassword");
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
response.Close();
}
}
catch (Exception exception)
{
}
}
while (j < agents.Length)
{
try
{
request = (FtpWebRequest)WebRequest.Create("ftp://myurl.com/mainfolder/" + agents[j] + "/");
request.Method = WebRequestMethods.Ftp.MakeDirectory;
request.Credentials = new NetworkCredential("myusername", "mypassword");
response = (FtpWebResponse)request.GetResponse();
responseStream = response.GetResponseStream();
response.Close();
}
catch (Exception exception)
{ }
j++;
}
MessageBox.Show("DONE");
}
它用于从服务器中删除过时的目录和文件。我有一个主文件夹,其中所有子文件夹都是数字,所有子文件夹仅包含文件(没有子文件夹的子文件夹)
服务器上的文件夹将存储在名为目录的ArrayList中。
存储在数据库中的目录ID将被加载到名为代理的String []中。
目录将在方兴未艾顺序进行排序,同样地,试剂在方兴未艾顺序(两者都是在这个项目中的数字,所以他们用数字排序)
如果服务器上存在的目录,但排序它不会存在于数据库中,它将被删除(首先删除它的所有文件,然后文件夹本身也会被删除)
如果一个目录在服务器上不存在,但存在于存储的目录列表中,它将在服务器上创建。
如果服务器和存储的目录列表中也存在目录,则不推荐使用的文件将被删除。服务器上相应目录中的文件称为文件,存储在数据库中的文件存储在名为dbFiles的String[]
中。
该函数实质上创建了要创建的文件夹,删除了要删除的文件夹并删除了要删除的文件并且工作正常。但是,我注意到在某些情况下,当发生服务器错误时,索引会下降,我不知道可能是什么原因。
例如I = 500(我不知道为什么)的服务器错误钓到的命令时,I = 100,为的情况下,我回落到100
我的问题是:为什么每当先前发生的错误被捕获时,我的索引就会回落?
当我100岁时,j会回落到状态吗?
如何防止此回退?
我发现了解决方案。
首先,这必须设置为避免这个问题:
request.KeepAlive = false;
其次,在抓这必须包括:
response.Close();
responseStream.Close();
当我们有一个responseStream打开,只
response.Close();
当一个responseStream没有打开。
我不确定这个问题的原因,但我认为C#正在为我的源代码做一个分支。
它不是J被重置,而是它没有被增加。以下是一个模拟您的控制流程的控制台程序。
对控制台的输出变化很大,取决于如果/ /抛出新的InvalidOperationException被注释掉或不。这是你的while(!reader.EndOfStream)。
老实说这个流程非常复杂。如果把这种方法分解成一些大小的部分,你可能会得到很好的服务。
class Program
{
static void Main(string[] args)
{
int agentCount = 1000;
int directoriesCount =100;
int fileCount = 100;
int dbFilesCount = 100;
int j = 0;
for (int i = 0; i < directoriesCount; i++)
{
Console.WriteLine("I : {0}", i);
try
{
while ((j < agentCount))
{
try
{
}
catch (Exception exception)
{ }
j++;
Console.WriteLine("J : {0}", j);
}
if (true)
{
//throw new InvalidOperationException("Some error"); UnComment and see
while (false)
{
}
int r = 0;
for (int q = 0; q < fileCount; q++)
{
while ((r < dbFilesCount))
{
r++;
}
try
{
if ((r >= dbFilesCount))
{
}
}
catch (Exception exception)
{ }
}
j++;
Console.WriteLine("J : {0}", j);
}
else
{
while (false)
{
}
for (int k = 0; k < fileCount; k++)
{
}
}
}
catch (Exception exception)
{
}
}
while (j < agentCount)
{
try
{
}
catch (Exception exception)
{ }
j++;
Console.WriteLine("J : {0}", j);
}
Console.WriteLine("Done");
Console.ReadLine();
}
}
这是完成源代码的想法,但是我只会在我知道我的问题的答案时最终确定它。例如,关闭响应的位置取决于答案。 – 2010-09-14 23:25:05
你应该重构你的代码,以便FTP命令中,而不是复印功能和/粘贴那些FTP命令无处不在,你有一些像这样的流程:
String[] directories = ftpGetListing("ftp://myurl.com/mainfolder/");
String[] agents = Crawler.CrawlerDbUtils.getAllAgentIDs();
String[] combinedDirectories = getElementsInBothArray(directories, agents);
String[] serverOnlyDirectories = getElementsOnlyInFirstArray(directories, agents);
String[] agentOnlyDirectories = getElementsOnlyInFirstArray(agents, directories);
// step 1: delete all server only directories
ftpDeleteDirectories("ftp://myurl.com/mainfolder/", serverOnlyDirectories);
// step 2: create all agent only directories
ftpCreateDirectories("ftp://myurl.com/mainfolder/", agentOnlyDirectories);
// step 3: depricate all files
foreach(String dir in combinedDirectories)
{
String ftpDir = "ftp://myurl.com/mainfolder/" + dir + "/";
String[] serverFiles = ftpGetListing(ftpDir);
String[] agentFiles = Crawler.CrawlerDbUtils.getAllPictures(dir);
String[] serverOnlyFiles = getElementsOnlyInFirstArray(serverFiles, agentFiles);
foreach(String file in serverOnlyFiles)
{
ftpDeleteFile(ftpDir + file);
}
}
然后你只需要为ftpGetListing
,ftpDeleteDirectories
,ftpCreateDirectories
和ftpDeleteFile
实现真正简单的功能。噢,还有一些简单的数组操作函数,如:getElementsInBothArrays
和getElementsOnlyInFitstArray
。
这也是一个富有洞察力的评论,但我仍然不知道为什么我的索引从500重回100. – 2010-09-14 23:26:35
+1为他重构。 – 2010-09-15 04:11:42
“服务器错误被捕获”...它是什么? – 2010-09-14 21:44:51
你的代码有很多问题:1)永远不要发现异常并忽略它。它试图告诉你一些你需要知道的东西。 2)'FtpWebResponse','Stream'和'StreamReader'都实现了'IDisposable',所以你需要在'using'块中使用它们。 – 2010-09-14 21:56:15
@John Saunders:谢谢您的宝贵意见。我的答案:1)首先他们没有被忽略,我在MessageBox-es中调试时显示它们以查找可能的错误。 2)我不知道这一点,谢谢你的信息,我会upvote你,如果我有权利 – 2010-09-14 23:23:35