使用.NET进行FTP上传

5
我正在编写一个上传zip文件到ftp服务器的代码。令人惊讶的是,该代码对于小文件可以正常工作,但对于大文件会出现问题。我正在使用Stream对象,并注意到当尝试关闭流时(只针对大文件),我的代码会被卡住。如果我不关闭流,则代码可以正常运行(即使对于大文件也是如此)。有没有人看出为什么会发生这种情况。如果我不关闭流,是否可能在将来出现问题。
代码片段:
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(@"ftp://" + ftpServerIP + @"/" + fileInf.Name));
Stream strm = reqFTP.GetRequestStream();

代码会在上传的文件较大时停止响应,具体位置为:
strm.Close();

由于此部分位于try-catch中,因此没有异常。

我不知道如何获取堆栈跟踪。


1
你如何使用 FtWebRequest 类?你是否遇到了所有 FTP 服务器的问题,还是只有一个? - Wim Coenen
1
你说的“遇到问题”是什么意思?能否提供具体的堆栈跟踪或错误行为? - abc
抱歉,如果有人编辑了我的问题,你能再做一遍吗? - kobra
@abc Kobra 询问如果流没有关闭会不会有潜在的未来问题 - 没有堆栈跟踪。 - JoshJordan
你的意思是它卡在Close()这一行,还是在那里抛出了异常?如果是后者,你仍然需要堆栈跟踪;在catch块中放置一些Debug语句。如果是前者,你可能需要粘贴更多的代码。 - user24359
你是怎么解决这个问题的? - Jacob
2个回答

6

我不知道你在关闭流时具体遇到了什么错误,但在我们的应用程序中,我们会进行大量的大文件上传(视频和图像)。以下是我们如何向FTP流写入数据:

request.KeepAlive = false; // This eliminated some of our stream closing problems

using (Stream stream = request.GetRequestStream())
{
    stream.Write(file.Data, 0, file.Data.Length);
}

我认为使用using块将有效地自行执行Close调用,但也可能执行其他必要的清理。另外请注意,我关闭了FTP保持连接,这在我们上传到某些第三方FTP站点时会出现问题。
您真的应该查看特定的异常而不是捕获所有异常。错误消息很可能会告诉您出了什么问题。我们遇到的最常见的问题与主动模式和被动模式以及保持连接有关。
编辑:
为了发现当我们与CDN(这种情况发生得太频繁)有FTP问题时实际发生了什么,我们有时必须在应用程序中打开跟踪。请参阅此链接以获取有关如何启用跟踪的详细信息。另一个选择是使用像Wireshark这样的工具来嗅探您的应用程序和FTP服务器之间的对话。如果您可以看到FTP协议中发生的事情,您就有更好的机会解决问题。

谢谢。在我的代码中,KeepAlive是false,我尝试使用"using",但代码永远不会离开"using"块。关于错误,我没有收到任何异常,这使得跟踪问题变得困难。 - kobra
你是使用主动模式还是被动模式? - Jacob
当你说“这部分在try-catch中,没有异常”时,你是指catch块没有被执行还是try/catch掩盖了你的异常? - Jacob
我正在使用被动模式。捕获块没有被执行到。 - kobra
如果问题是与FTP服务器有关的问题,可以添加一些诊断问题的提示。 - Jacob

0

尝试使用这里的开源FTP组件可能是值得一试的...我曾经尝试过使用FtpWebRequest,但我的使用经验是负面的...速度慢,超时,因为很自然地,FtpWebRequest通过端口80而不是本机端口21工作...当我使用这个FTP组件时,情况发生了很大的变化,更加多功能和强大...

编辑:正如Jacob指出的我的明显错误和我对FtpWebRequest类的不合逻辑的看法,导致我相信某些奇怪和怪异的事情正在发生,以及它以某种方式通过HTTP进行了某些操作...嗯,Jacob一定有道理...这是框架中糟糕的命名约定的典型案例...谢谢Jacob!

希望这可以帮助到您, 最好的问候, 汤姆。


FtpWebRequest从未为我们使用端口80。你从哪里得到这个信息的? - Jacob
@Jacob:为什么叫FtpWebRequest呢?它使用http协议与FTP服务器通信...关键字就在名字里!为什么要使用WebRequest来创建FtpWebRequest?如果你不同意...那为什么没有专门的ftp组件直接与21号端口通信呢?它是围绕这个WebRequest类封装的。 - t0mm13b
2
这只是一个糟糕的名称。HttpWebRequest使用端口80,而FtpWebRequest使用端口21。 WebRequest是两者的抽象基类。 - Jacob
@Jacob:实际上我一直以为有些奇怪和怪异的事情正在发生,因为我觉得它太慢了……哈哈……哦天啊……会编辑答案指出这一点。 - t0mm13b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接