You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ListDirectoryDetails获取FTP文件时文件名缺失及条目异常问题

解决FTP目录列表返回异常:条目多余+文件名缺失问题

看起来你在用C#的FtpWebRequest获取FTP目录文件时踩了个常见的坑——返回的列表不仅多了两个条目,前两个还出现了文件名缺失的情况,我来帮你拆解问题根源,再给你针对性的解决方案:

问题到底出在哪?

首先得明确:你用的ListDirectoryDetails方法,返回的是带完整文件属性的目录列表(类似你在终端敲ls -l或者Windows里用dir命令的输出),不是单纯的文件名列表。这就导致两个核心问题:

  1. 多出的两个条目:FTP服务器默认会在目录列表里返回.(当前目录)和..(上级目录)这两个导航用的特殊项,这就是你看到数组多了2个条目的原因。
  2. 文件名缺失:你直接把每一行完整内容存进列表,但这些行里包含了权限、修改时间、文件大小等元数据,不是纯文件名。而前两行刚好是.和..,它们的“文件名”就是.和..,如果你的后续处理逻辑是提取文件名,可能会误判成“缺失”。

两种解决方案任你选

方案1:直接获取纯文件名列表(最简单)

如果你不需要文件权限、大小这些元数据,直接把请求方法改成ListDirectory就行——这个方法返回的就是干净的文件名列表,不会包含.、..,也没有额外的属性信息:

public static string[] GetFilesInDirectory(string requestUriString, string username, string password) 
{ 
    var lines = new List<string>(); 
    try 
    { 
        var request = (FtpWebRequest)WebRequest.Create(requestUriString); 
        request.Credentials = new NetworkCredential(username, password); 
        // 替换成ListDirectory,只拿纯文件名
        request.Method = WebRequestMethods.Ftp.ListDirectory; 
        request.UsePassive = true; 

        using (WebResponse response = (FtpWebResponse)request.GetResponse()) 
        using (Stream responseStream = response.GetResponseStream()) 
        using (var reader = new StreamReader(responseStream)) 
        { 
            string line; 
            while ((line = reader.ReadLine()) != null) 
            { 
                try 
                { 
                    lines.Add(line); 
                } 
                catch (Exception ex) 
                { 
                    MessageBox.Show(ex.Message); 
                } 
            } 
        } 
    } 
    catch (Exception ex) 
    { 
        throw new Exception("An error occurred connecting to the website.", ex); 
    } 
    return lines.ToArray();
}

方案2:解析详细列表,过滤特殊项并提取文件名(适合需要文件属性的场景)

如果你需要文件的权限、大小这些信息,那得手动解析ListDirectoryDetails的输出。注意不同FTP服务器的输出格式不一样(Unix/Linux和Windows IIS的格式差异很大),这里给你一个通用的解析思路:

  1. 先过滤掉.和..这两个特殊条目
  2. 根据服务器的输出格式,从每行里提取出文件名

下面是针对Unix风格FTP服务器的解析示例代码:

// 解析ListDirectoryDetails返回的详细行,提取文件名
public static List<string> ParseFtpDirectoryLines(string[] directoryLines)
{
    var validFileNames = new List<string>();
    foreach (var line in directoryLines)
    {
        var trimmedLine = line.TrimEnd();
        // 跳过当前目录和上级目录的条目
        if (trimmedLine.EndsWith(".") || trimmedLine.EndsWith(".."))
            continue;
        
        // Unix格式的行:分割后,文件名从第8个元素开始(前面是权限、链接数、用户、组、大小、月、日、时间)
        var lineParts = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
        if (lineParts.Length >= 8)
        {
            // 处理带空格的文件名,把后面的部分拼接起来
            string fileName = string.Join(" ", lineParts.Skip(7));
            // 去掉文件名可能带的引号
            fileName = fileName.Trim('"');
            validFileNames.Add(fileName);
        }
    }
    return validFileNames;
}

然后在你的原方法里,调用这个解析方法来处理结果:

// 原方法中获取lines之后
var parsedFileNames = ParseFtpDirectoryLines(lines.ToArray());
return parsedFileNames.ToArray();

小提示

调试的时候可以把lines里的每一行内容打印出来,看看你的FTP服务器返回的具体格式是什么样的——这样你就能更精准地调整解析逻辑,比如如果是Windows IIS的FTP服务器,输出格式会是类似08-10-23 12:00PM <DIR> docs这样的,解析逻辑就得对应调整啦。

内容的提问来源于stack exchange,提问作者David B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:19:12