【问题标题】:How to check if file exists in remote folder via FTP?如何通过FTP检查文件是否存在于远程文件夹中?
【发布时间】:2012-07-15 20:17:11
【问题描述】:

我想检查远程文件夹的内容,并确定该文件夹中是否存在特定文件(我只通过文件名检查,所以冷静:D)

示例:我想检查文件夹/testftp 中是否包含textfile.txt 文件。

我这样做是为了获取文件夹内容:

      FtpWebRequest request = (FtpWebRequest)WebRequest.Create("myftpaddress");
        request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;


        request.Credentials = new NetworkCredential("uid", "pass");

        FtpWebResponse response = (FtpWebResponse)request.GetResponse();

        Stream responseStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(responseStream);
        Console.WriteLine(reader.ReadToEnd());

        Console.WriteLine("Directory List Complete, status {0}", response.StatusDescription);

        reader.Close();
        response.Close(); 

它在控制台中写入:

-rw-r--r--   1 6668   userftp 91137 jul 16 23:20 file1.txt
-rw-r--r--   1 468    userftp   137 jul 16 18:40 file2.swf

并将完整的流响应写入控制台,如何仅获取文件名?有没有更简单的方法?

【问题讨论】:

标签: c# .net


【解决方案1】:

尝试下载文件会更容易。如果你得到StatusCode 表明文件不存在,你就知道它不存在。

可能比过滤ListDirectoryDetails 的结果要少。

更新

为了澄清,你需要做的就是:

FtpWebResponse response = (FtpWebResponse) request.GetResponse();
bool fileExists = (response.StatusCode != BAD_COMMAND);

我认为 BAD_COMMAND 将是 FtpStatusCode.CantOpenData 但我不确定。这很容易测试。

【讨论】:

  • 如果文件存在,您将承担下载费用。
  • 只有当你调用reader.ReadToEnd()时,才需要判断资源是否存在。
  • 不明白为什么不调用reader.ReaderToEnd()会阻止FTP服务器发送文件的内容?当然,关闭响应流可能会在收到所有字节之前关闭连接。
  • 在为 fileExists 赋值之前,您只需要在客户端上提供响应标头即可。如果该文件不存在,这就是你得到的全部。如果文件确实存在,您可能会在连接关闭之前获得几毫秒的响应正文。这几毫秒的数据量可能比完整列表所获得的数据更多或更少。
  • 好的,那符合我的直觉。希望没有大的 TCP 窗口或大的带宽延迟产品。无论如何,看起来 HatSoft 指出了正确的答案...使用WebRequestMethods.Ftp.GetDateTimestamp,这与您的答案类似,但没有可能获得大的响应。
【解决方案2】:
string listing = reader.ReadToEnd();

// find all occurrences of the fileName and make sure
// it is bounded by white space or string boundary.

int startIndex = 0;
bool exists = false;
while (true)
{
    int index = listing.IndexOf(fileName, startIndex);
    if (index == -1) break;

    int leadingIndex = index - 1;
    int trailingIndex = index + fileName.Length;

    if ((leadingIndex == -1 || Char.IsWhiteSpace(listing[leadingIndex]) &&
        (trailingIndex == list.Length || Char.IsWhiteSpace(listing[trailingIndex]))
    {
        exists = true;
        break;
    }

    startIndex = trailingIndex;
}

正则表达式版本:

string pattern = string.Format("(^|\\s){0}(\\s|$)", Regex.Escape(fileName));
Regex regex = new Regex(pattern);

string listing = reader.ReadToEnd();
bool exists = regex.IsMatch(listing);

【讨论】:

  • 如果列表中包含文件textfile.txt.old怎么办?这将与您的代码错误地匹配。
  • 您可以使用 RegEx 与周围的空白/换行符进行匹配,但只需通过尝试下载文件来测试文件是否存在 :-)
  • 我在第一篇文章中写过 - 我只检查文件名,它们总是不同的,因为我将比较随机的 md5 加密字符串,所以这就是我所需要的?
  • @pawel 希望如此。我已经调整了我的答案以适应 Eric 的担忧,尽管它不像 RegEx 那样短(这需要我多花一些时间来整理,因为我每 6 个月使用一次 RegEx,并且永远记不起详细信息)给定平台;我认为您必须在正则表达式中转义文件名。)
猜你喜欢
  • 1970-01-01
  • 2012-07-07
  • 2011-05-07
  • 2022-11-25
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
相关资源
最近更新 更多