【问题标题】:VB.NET to download latest file name with timestamp in its name from FTP serverVB.NET 从 FTP 服务器下载带有时间戳的最新文件名
【发布时间】:2017-02-28 02:48:36
【问题描述】:

我想将一个文件从我的 FTP 服务器拉到我的本地驱动器中。然而,这样做最困难的部分是文件名是一个每天都在变化的时间戳。无论文件如何随日期发生变化,程序都应下载该文件;年、月、时、分和秒。名称的格式始终相同。文件名示例在下面以粗体显示。请指教!

例如,
用户名 - meUser
密码 - mepswrd
以及 FTP 的 URL
/afea/euser/aefe/aole/efa/ 以及下载后我希望文件保存的路径。
C:\Users\alae\Desktop\loaef
并且文件格式为
20160223.171234.BA_DESRP_20160121.txt

文件中唯一不变的部分是BA_DESRP,所有其他部分都可以更改,因为它是一个时间戳。

这是我开始的代码:

Const lf As String = "C:\Users\alae\Desktop\loaef"
Const rf As String = "/afea/euser/aefe/aole/efa/"
Const ht As String = "host"
Const un As String = "username"
Const pw As String = "password"

Dim URI As String = ht & rf
Dim ftp As System.Net.FtpWebRequest = _
    CType(FtpWebRequest.Create(URI), FtpWebRequest)

ftp.Credentials = New _
    System.Net.NetworkCredential(un, pw)

【问题讨论】:

  • 您需要先获取目录中的文件列表,如果有多个文件,然后再获取您要下载的文件。查找 WebRequestMethods.Ftp.ListDirectoryDe​​tails
  • 好的,但是所有这些文件(其中多个)都具有相似的格式(时间戳),它们会发生变化。你能举个例子吗?我也会看看你的建议吗?
  • 想想吧。文件名是String,所以您要问的基本上是如何确定String 是否包含另一个String。我非常有信心,如果您需要更多信息,您会在网络上找到大量有关如何执行此操作的信息。
  • FTP 文件夹中是否总是只有一个BA_DESRP 文件?
  • 所以让我确保我理解这个问题。您下载的目录将包含多个具有相同文件命名约定的文件,但是每当您去那里获取文件时,您总是想获取最新的文件,对吗?所以只要这个目录中没有数千个文件,.Ftp.ListDirectoryDe​​tails 方法应该允许你在这里做你想做的事。返回文件列表后,您可以检查时间戳,也可以根据文件名自行计算,以确定哪个是最新的。我将添加返回文件列表的代码

标签: vb.net ftp timestamp filenames ftpwebrequest


【解决方案1】:

FtpWebRequest(或 .NET 框架中随时可用的任何其他功能)没有简单的方法。你必须:

  • 使用WebRequestMethods.Ftp.ListDirectory 列出远程目录
  • 将返回的列表过滤为包含BA_DESRP 的列表
  • 从中选择最新的
  • 然后下载
Dim url As String = "ftp://ftp.example.com/remote/path/"
Dim credentials As NetworkCredential = New NetworkCredential("username", "password")
Const localPath = "C:\local\path"

Dim listRequest As FtpWebRequest = WebRequest.Create(url)
listRequest.Method = WebRequestMethods.Ftp.ListDirectory
listRequest.Credentials = credentials

Dim latest As String = Nothing

Using listResponse As FtpWebResponse = listRequest.GetResponse(),
      listStream As Stream = listResponse.GetResponseStream(),
      listReader As StreamReader = New StreamReader(listStream)
    While Not listReader.EndOfStream
        Dim filename As String = listReader.ReadLine()

        If filename.Contains("BA_DESRP") Then
            Console.WriteLine("Found {0} ...", filename)

            If (latest Is Nothing) OrElse (latest < filename) Then
                latest = filename
            End If
        End If
    End While
End Using

If Not latest Is Nothing Then
    Console.WriteLine("Downloading {0} ...", latest)
    Dim webClient As New WebClient()
    webClient.Credentials = credentials
    webClient.DownloadFile(url + latest, Path.Combine(localPath, latest))
End If

或者使用其他功能更强大的 FTP 库。

例如WinSCP .NET assembly:

Const localPath = "C:\local\path\"
Const remotePath = "/remote/path"

Dim sessionOptions As New SessionOptions
With sessionOptions
    .Protocol = Protocol.Ftp
    .HostName = "ftp.example"
    .UserName = "username"
    .Password = "password"
End With

Using session As New Session
    session.Open(sessionOptions)

    Dim latest As RemoteFileInfo =
        session.ListDirectory(remotePath).Files.
            Where(Function(file) file.Name.Contains("BA_DESRP")).
            OrderByDescending(Function(file) file.Name).
            FirstOrDefault()

    If Not latest Is Nothing Then
        Console.WriteLine("Downloading {0} ...", latest)
        session.GetFiles(latest.FullName, localPath).Check()
    End If
End Using

如果您可以使用实际的文件时间戳(而不是其名称中的时间戳),那就更简单了。见Downloading the most recent file

(我是 WinSCP 的作者)

【讨论】:

    【解决方案2】:

    这将为您提供目录中的文件列表。由于您的文件名已经包含时间戳,您只需从文件名中解析出来,然后最终将每个时间戳存储在一个变量中,然后您可以将下一个文件的时间戳与之进行比较。如果下一个文件大于变量中的值,请分配该值。最后,当你完成时,你的 var 应该反映你需要的文件名,在那个阶段你可以调用 download 方法来获取文件。

     Dim request As FtpWebRequest = WebRequest.Create("ftp://" & "servername" & "/" & "directory" & "/*")
        request.Method = WebRequestMethods.Ftp.ListDirectory
        request.Credentials = New NetworkCredential("username", "password")
    
        Using reader As New StreamReader(request.GetResponse().GetResponseStream())
            Do Until reader.EndOfStream
                Console.WriteLine(reader.ReadLine())
            Loop
        End Using
    

    由于您说文件有数千个,因此这条路线可能不是您的最佳选择。如果您不限于 .NET,则可能需要探索其他选项,例如使用 ftp 客户端,您可以在其中通过文件的实际时间戳进行搜索...

    【讨论】:

    • 感谢您的建议和代码示例。看起来不错。你说的是什么替代方案,什么样的FTP客户端,FTP客户端是软件吗,能给我举个例子吗?
    • 是的,但还有一个建议。你知道你每次都在寻找哪一天吗?所以当你运行它时,它总是在寻找今天或昨天创建的文件吗?如果您知道这一点,您当然可以使用我发布的代码限制您的搜索条件,请参阅使用的通配符,这可以帮助消除对整个目录的搜索; \WebRequest.Create("ftp://" & "服务器名" & "/" & "目录" & "/20160223*")
    猜你喜欢
    • 2015-07-27
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    相关资源
    最近更新 更多