gpt4 book ai didi

c# - 检查 FTP 上是否有文件或文件夹

转载 作者:太空宇宙 更新时间:2023-11-03 22:54:40 26 4
gpt4 key购买 nike

我从 FTP 读取文件/文件夹列表。

问题是我不知道是文件还是文件夹。目前我正在检查字符串是否有扩展名。如果是,则为文件,否则为文件夹。但这还不够好,它可以存在不带扩展名的文件和带扩展名的文件夹(例如,文件夹名称可以是 FolderName.TXT)

这是我用来列出文件夹内容的代码:

public async Task<CollectionResult<string>> ListFolder(string path)
{
try
{
FtpWebRequest ftpRequest = null;
var fileNames = new List<string>();
var res = new CollectionResult<string>();
ftpRequest = ftpBuilder.Create(path, WebRequestMethods.Ftp.ListDirectory);
using (var ftpResponse = (FtpWebResponse)await ftpRequest.GetResponseAsync())
using (var ftpStream = ftpResponse.GetResponseStream())
using (var streamReader = new StreamReader(ftpStream, Encoding.UTF8))
{
string fileName = streamReader.ReadLine();
while (!string.IsNullOrEmpty(fileName))
{
fileNames.Add(Path.Combine(path, fileName.Substring(fileName.IndexOf('/') + 1, fileName.Length - fileName.IndexOf('/') - 1)));
fileName = streamReader.ReadLine();
}
}
ftpRequest = null;
res.ListResult = fileNames;
return res;
}
catch (Exception e)
{
e.AddExceptionParameter(this, nameof(path), path);
throw;
}
}

如果我能检测到 while 循环中是否有文件或文件夹,那将是最好的,但仅从字符串中检测是不可能的。

感谢您的帮助。


编辑

我发现了类似的问题。 C# FTP, how to check if a Path is a File or a Directory?但是问题很老,没有很好的解决方案。


编辑:解决方案

 public async Task<CollectionResult<Tuple<string, bool>>> ListFolder(string path)
{
try
{
FtpWebRequest ftpRequest = null;
var fileNames = new CollectionResult<Tuple<string, bool>>();
fileNames.ListResult = new List<Tuple<string, bool>>();
if (!(IsFtpDirectoryExist(path)))
{
throw new RemoteManagerWarningException(ErrorKey.LIST_DIRECTORY_ERROR, fileNames.ErrorMessage = $"path folder {path} not exists");
}
ftpRequest = ftpBuilder.Create(path, WebRequestMethods.Ftp.ListDirectoryDetails);
using (var ftpResponse = (FtpWebResponse)await ftpRequest.GetResponseAsync())
using (var ftpStream = ftpResponse.GetResponseStream())
using (var streamReader = new StreamReader(ftpStream, Encoding.UTF8))
{
while (!streamReader.EndOfStream)
{
string line = streamReader.ReadLine();
string[] tokens = line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
// is number:
Regex rgx = new Regex(@"^[\d\.]+$");
var isExternalFtpOrUnixDirectoryStyle = !(rgx.IsMatch(line[0].ToString()));
string name = string.Empty;
bool isFolder = false;

if (isExternalFtpOrUnixDirectoryStyle)
{
name = tokens[8];
var permissions = tokens[0];
isFolder = permissions[0] == 'd';
}
else
{
tokens = line.Split(new[] { ' ' }, 4, StringSplitOptions.RemoveEmptyEntries);
name = tokens[3];
isFolder = tokens[2] == "<DIR>";
}
name = Path.Combine(path, name);
Tuple<string, bool> tuple = new Tuple<string, bool>(name, isFolder);
fileNames.ListResult.Add(tuple);
}
}
ftpRequest = null;
return fileNames;
}
catch (Exception e)
{
e.AddExceptionParameter(this, nameof(path), path);
throw;
}
}

最佳答案

FtpWebRequest 或任何其他 .NET 框架的内置功能无法以可移植的方式识别目录条目是否为文件的子目录。不幸的是,FtpWebRequest 不支持 MLSD 命令,这是在 FTP 协议(protocol)中检索具有文件属性的目录列表的唯一可移植方式。另见 Checking if object on FTP server is file or directory .

您的选择是:

  • 对文件名执行操作,该操作肯定对文件失败但对目录成功(反之亦然)。 IE。您可以尝试下载“名称”。如果成功,它是一个文件,如果失败,它是一个目录。
  • 您可能很幸运,在您的特定情况下,您可以通过文件名从目录中区分文件(即所有文件都有扩展名,而子目录没有)
  • 您使用长目录列表(LIST 命令 = ListDirectoryDe​​tails 方法)并尝试解析特定于服务器的列表。许多 FTP 服务器使用 *nix 样式的列表,您可以在其中通过条目最开头的 d 标识目录。但是许多服务器使用不同的格式。

    有关实现解析的一些示例,请参阅:
    *nix 格式:Parsing FtpWebRequest ListDirectoryDetails line
    DOS/Windows 格式:C# class to parse WebRequestMethods.Ftp.ListDirectoryDetails FTP response


如果您想避免解析特定于服务器的目录列表格式的麻烦,请使用支持 MLSD 命令和/或解析各种 LIST 列表的第 3 方库格式;和递归下载。

例如 WinSCP .NET assembly你可以使用 Sesssion.ListDirectory :

// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "example.com",
UserName = "user",
Password = "mypassword",
};

using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);

RemoteDirectoryInfo directory = session.ListDirectory("/home/martin/public_html");

foreach (RemoteFileInfo fileInfo in directory.Files)
{
if (fileInfo.IsDirectory)
{
// directory
}
else
{
// file
}
}
}

如果服务器支持,WinSCP 在内部使用 MLSD 命令。如果没有,它会使用 LIST 命令并支持数十种不同的列表格式。

(我是 WinSCP 的作者)

关于c# - 检查 FTP 上是否有文件或文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45955461/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com