Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在.NET应用程序中从FTP协议获取目录文件大小_.net_Windows_Ftp_Winscp - Fatal编程技术网

如何在.NET应用程序中从FTP协议获取目录文件大小

如何在.NET应用程序中从FTP协议获取目录文件大小,.net,windows,ftp,winscp,.net,Windows,Ftp,Winscp,我目前正在制作一个小型的.NET控制台应用程序,用于将我的一些文件自动备份到服务器上。我遇到的问题是,我这边的天气不好,导致了一些电力和网络中断。在这段时间里,我注意到我的大部分文件没有通过或损坏。我想知道是否有办法获得另一端文件夹的大小,并查看文件名、文件数和总目录大小是否匹配。我尝试过WinSCP和NcFTP作为通过网络传输文件的方法,但我没有看到任何关于获得适当文件大小的信息 这几乎是windows到windows的传输,因此,如果有命令行参数通过FTP客户端返回一个大小,那就太好了。没有

我目前正在制作一个小型的.NET控制台应用程序,用于将我的一些文件自动备份到服务器上。我遇到的问题是,我这边的天气不好,导致了一些电力和网络中断。在这段时间里,我注意到我的大部分文件没有通过或损坏。我想知道是否有办法获得另一端文件夹的大小,并查看文件名、文件数和总目录大小是否匹配。我尝试过WinSCP和NcFTP作为通过网络传输文件的方法,但我没有看到任何关于获得适当文件大小的信息


这几乎是windows到windows的传输,因此,如果有命令行参数通过FTP客户端返回一个大小,那就太好了。

没有标准的方法来请求“此目录中文件的总大小”。您可以通过
size file.txt
单独请求每个文件的大小,也可以请求整个目录的
ls-l
,并解析文件大小。

我认为最好的办法是获取完整的文件列表,然后一次发送一个。如果传输期间连接失败,则文件上载将失败。如果文件上载成功,则可以从列表中删除该文件名

正如您在标记中提到的NET,也许您应该寻找一个如何在C#中执行它的示例。Net将是类似的,但它会给你一个想法


您可以获得如图所示的目录列表。

没有标准的FTP命令来检索目录大小

您必须递归地迭代所有子目录和文件,并对大小求和

对于.NET framework/
FtpWebRequest
,这并不容易,因为它不支持
MLSD
命令,这是在FTP协议中检索具有文件属性的目录列表的唯一可移植方法

您所能做的就是使用
LIST
命令(
ListDirectoryDetails
)并尝试解析特定于服务器的列表。许多FTP服务器使用*nix样式的列表。但许多服务器使用不同的格式。以下示例使用*nix格式:

static long CalculateFtpDirectorySize(string url, NetworkCredential credentials)
{
    FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);
    listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
    listRequest.Credentials = credentials;

    List<string> lines = new List<string>();

    using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse())
    using (Stream listStream = listResponse.GetResponseStream())
    using (StreamReader listReader = new StreamReader(listStream))
    {
        while (!listReader.EndOfStream)
        {
            lines.Add(listReader.ReadLine());
        }
    }

    long result = 0;
    foreach (string line in lines)
    {
        string[] tokens =
            line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
        string name = tokens[8];
        string permissions = tokens[0];

        string fileUrl = url + name;

        if (permissions[0] == 'd')
        {
            result += CalculateFtpDirectorySize(fileUrl + "/", credentials);
        }
        else
        {
            result += long.Parse(tokens[4]);
        }
    }

    return result;
}

如果您的服务器使用DOS/Windows列表格式,请参阅


或者,您可以使用支持现代
MLSD
命令的第三方FTP客户端实现

例如,我们支持这一点

它甚至有简便的方法,使计算目录大小变得简单:

var files = session.EnumerateRemoteFiles("/", null, EnumerationOptions.AllDirectories);
long size = files.Select(fileInfo => fileInfo.Length).Sum();
完整的代码如下所示:

SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "ftp.example.com",
    UserName = "username",
    Password = "password",
};

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

    var files = session.EnumerateRemoteFiles("/", null, EnumerationOptions.AllDirectories);
    long size = files.Select(fileInfo => fileInfo.Length).Sum();
}

(我是WinSCP的作者)

你为什么选择FTP?你对其他协议开放吗?根据其他协议,我可以试一试。我之所以使用FTP,是因为速度太快。对于包含大文件的目录,这种方法非常繁琐,并且试图通过网络解析它,但总的来说,这似乎是可行的。谢谢你的帮助。
SessionOptions sessionOptions = new SessionOptions
{
    Protocol = Protocol.Ftp,
    HostName = "ftp.example.com",
    UserName = "username",
    Password = "password",
};

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

    var files = session.EnumerateRemoteFiles("/", null, EnumerationOptions.AllDirectories);
    long size = files.Select(fileInfo => fileInfo.Length).Sum();
}