VB.NET遍历文件和目录

5

我正在开发一个VB.NET程序,它可以自动将我的工作备份到FTP服务器上。目前,我能够通过使用以下方法指定文件名来上传单个文件:

     'relevant part - above is where FTP object is instantiated
       Dim _FileStream As System.IO.FileStream = _FileInfo.OpenRead()

            Try
                'Stream to which the file to be upload is written
                Dim _Stream As System.IO.Stream = _FtpWebRequest.GetRequestStream()

                'Read from the file stream 2kb at a time
                Dim contentLen As Integer = _FileStream.Read(buff, 0, buffLength)

                'Till Stream content ends
                Do While contentLen <> 0
                    ' Write Content from the file stream to the FTP Upload Stream
                    _Stream.Write(buff, 0, contentLen)
                    contentLen = _FileStream.Read(buff, 0, buffLength)
                Loop
                _Stream.Close()
                _Stream.Dispose()
                _FileStream.Close()
                _FileStream.Dispose()

                ' Close the file stream and the Request Stream


            Catch ex As Exception
                MessageBox.Show(ex.Message, "Upload Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try

现在我希望能够遍历一个目录(其中包含子目录),并递归调用上面的函数。我在获取目录中的文件方面遇到了问题。
我的问题是,如何循环遍历并将每个文件发送到上面的上传函数?我可以将文件名发送到数组中,还是有一些系统对象来处理这个问题(例如System.IO.Directory)?
我正在尝试做的伪代码:
                For Each Sub_directory In Source_directory

                     For Each File in Directory
                       'call the above code to transfer the file
                     Next

                'start next subdirectory
                Next

我正在尝试复制整个目录结构,包括子目录。我的第一次尝试将所有文件都倒入一个目录中。

3个回答

10

您可以使用递归来遍历每个目录和文件,如下所示:

Public Shared Sub ForEachFileAndFolder(ByVal sourceFolder As String, _
                                       ByVal directoryCallBack As Action(Of DirectoryInfo), _
                                       ByVal fileCallBack As Action(Of FileInfo))

    If Directory.Exists(sourceFolder) Then
        Try
            For Each foldername As String In Directory.GetDirectories(sourceFolder)
                If directoryCallBack IsNot Nothing Then
                    directoryCallBack.Invoke(New DirectoryInfo(foldername))
                End If

                ForEachFileAndFolder(foldername, directoryCallBack, fileCallBack)
            Next
        Catch ex As UnauthorizedAccessException
            Trace.TraceWarning(ex.Message)
        End Try

        If fileCallBack IsNot Nothing
            For Each filename As String In Directory.GetFiles(sourceFolder)
                fileCallBack.Invoke(New FileInfo(filename))
            Next
        End If
    End If
End Sub

编辑: Delegates 的用法:

ForEachFileAndFolder("yourPath", AddressOf dirAction, Addressof fileAction)

Public Sub dirAction(Byval dirInfo As DirectoryInfo)
    ' do something here '
End Sub

对于 FileAction 也是一样。


谢谢Bobby,这似乎是我正在寻找的东西。但是,我从未将"As Action"用作参数。在对ForEachFileAndFolder的初始调用中,我应该传递什么作为directoryCallBack和fielCallBack?这些参数应该是我想要在每个对象上运行的函数吗?例如,FTP传输函数=fileCallBack? - tpow
@cinqoTimo:添加了一个关于如何使用委托的示例。还在函数中添加了一个检查,以防传入Nothing,这样你就可以不对文件夹进行任何操作了。 - Bobby
你真行,它起作用了... 所以委托基本上是一个私有函数。我有一个大致的想法,但我没有面向对象编程的背景 - 主要是HTML/CSS/PHP。感谢您的时间。 - tpow
1
@cinqoTimo:从技术上讲,委托只是子程序或函数的占位符。您可以传递与指定签名匹配的任何内容。例如,在VB.NET中您可能看不到这一点,但在C#和其他语言中,事件只是被调用的委托集合。 - Bobby
@Bobby 很好的解释委托。 - Sandeep Thomas

2

您需要分别处理目录和文件,但这仍然很简单。

System.IO.DirectoryInfo包含指定目录中的文件和子目录列表。查找directories和files属性。

您想要做的是指定一个函数,该函数将首先读取DirectoryInfo中的所有文件,然后再读取目录。对于文件,您可以根据自己的需求进行操作(我认为是上传),一旦到达目录,就使用子目录作为参数递归调用您的函数。这将遍历所有子目录和文件。

伪代码(我称其为伪代码,因为我不知道确切的语法)

Sub UploadDirectory(oDirInfo as DirectoryInfo)
For each oFile as FileInfo in oDirINfo.Files 'Do your thing Next
For each oDir as DirectoryInfo as oDirInfo.Directories ' 如果需要分离目录,则执行某些操作 UploadDirectory(odir) End sub

希望这有所帮助。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接