惊天大Bug?让人呕血的FtpWebRequest

本来以为2.0开始内置了FtpWebRequest,以后不用再受没有更新保障的第三方Ftp类库的限制,结果今天遇到的问题,让我呕血三升不得其解。看来又得自己写FtpClient的类了。言归正传,先说问题

以前用到Ftp上传很多都是一次性的操作,所以如果:

FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create("url");

之 后的话就可以上传,下载,或者什么的,之后就直接退出了事。结果现在的需求会涉及很多比较具有持续性的操作,比如进入一个根目录,然后list,判断是否 存在一个目录,如果存在就cd进入,不存在就md创建这个目录,之后进入,再上传文件到目录中。这个时候麻烦产生了。一般来说为了安全性的原因,设置 FTP的时候都设置了锁定用户在主目录的选项。比如Serv-U如下:

image

这个时候第一次执行,很好,一点问题都没有,但是第二次执行的时候麻烦就来了。

比如Ftp的根url为 Ftp://xx.xx.xx.xx/ 要进入的目录为test,第一次在FtpWebRequest.Create("Ftp://xx.xx.xx.xx/");的时候,我们list得到的是根目录的内容,但是在上传完成后进行第二次操作,这个时候创建FtpWebRequest对象的url仍然是 Ftp://xx.xx.xx.xx/ 但是再执行list的时候取出的确是test目录下的文件列表!!

之后为了测试我去掉了 image 之后执行就一点问题都没有了。

但 是注意,这里的两次操作是两个不同的FtpWebRequest对象,却保持了同一个操作的Session。且让人郁闷的是,FtpWebRequest 没有提供任何显示关闭连接的方法,也没有任何改变工作目录的方法,即使是新建的FtpWebRequest对象使用了不同的url,仍然不会改变其当初的 工作目录,后来查了一下Serv-U的日志,发现根本就没法送改变工作目录的指令………

为了FtpWebRequest的对象不保持连 接的上下文,我把KeepAlive属性设为false,结果出现了第二个让我呕血的问题。当第二次执行操作的时候,报错了,如果是连本机的FTP则报返 回226 transfercomplete的异常,如果是远程的ftp则报无法访问已经释放的对象……………

不知道如此一个脑残的东西是如何通过层层审核进入.NET的类库的。呕血的FtpWebRequest

如果有兴趣的可以自己实验一下,验证一下结果,测试的case为:

while(true){

创建FtpwebRequest

列表目录

创建FtpWe

上传文件

此处打断点

}

还可以通过Serv-U看看其中的log,看看到底发送了些什么ftp指令

如果有达人发现是我哪里搞错了也请告之,万分感谢。

posted on 2009-11-13 17:10  亚历山大同志  阅读(10579)  评论(17编辑  收藏  举报

导航