这个CopyFiles子程序负责完成这个应用程序中的绝大多数工作。它负责取得源目录下的一个文件列表,然后把它们复制到目的目录下。另外,它还创建了一个ConsoleProgressBar对象来管理进度条:
四、 引擎—CopyFiles
这个CopyFiles子程序负责完成这个应用程序中的绝大多数工作。它负责取得源目录下的一个文件列表,然后把它们复制到目的目录下。另外,它还创建了一个ConsoleProgressBar对象来管理进度条:
Private Sub CopyFiles(ByVal srcDir As String, ByVal destDir As String)
Const BufferSourceTopLine As Integer = 8
Const BufferDestinationTopLine As Integer = 7
Dim rowIndex As Integer = 7
Dim originalForegroundColor As ConsoleColor = Console.ForegroundColor
Console.CursorVisible = False
Console.Clear()
Dim numberOfFiles As Integer
numberOfFiles = My.Computer.FileSystem.GetFiles(srcDir).Count
Dim PB As New ConsoleProgressBar(numberOfFiles)
DisplayHeader(srcDir, destDir)
Dim fileCounter As Integer = 1
For Each f As String In My.Computer.FileSystem.GetFiles(srcDir)
Dim fi As New System.IO.FileInfo(f)
Console.ForegroundColor = ConsoleColor.Green
Console.SetCursorPosition(0, rowIndex)
Console.Write(fi.Name)
If rowIndex < Console.WindowHeight - 1 Then
rowIndex += 1
Else
Console.MoveBufferArea(0,BufferSourceTopLine, _
Console.WindowWidth, _
Console.WindowHeight - _
BufferSourceTopLine, _
0, _
BufferDestinationTopLine)
End If
My.Computer.FileSystem.CopyFile(fi.FullName, destDir &"\" & fi.Name)
pb.Update( fileCounter)
fileCounter += 1
Next
Console.ForegroundColor = originalForegroundColor
Console.SetCursorPosition(0, Console.WindowHeight - 1)
Console.CursorVisible = True
End Sub
首先,该代码保存当前的ForegroundColor。然后,它使用另外一种新特征把CursorVisible属性设置为False。在清除控制台窗口后,它检索在源目录下的文件个数并且使用这个数字作为ConsoleProgressBar构造器的最大值。稍后,我还要讨论有关于 ConsoleProgressBar的细节信息。
我调用DisplayHeader子程序来把一些有关复制操作的信息打印到控制台窗口。由于其功能非常类似于DisplayUsage子程序,所以我在此省略对其细节的讨论。
我使用了一个“For...Each”循环来遍历在源目录下的所有文件,并使用了一个rowIndex变量来跟踪要把文件名打印到控制台的哪一行。随着循环的不断执行,rowIndex每次增加1,直到到达控制台窗口的底部为止。一旦到达控制台窗口的底部,我利用另外一个新控制台应用程序特征— MoveBufferArea方法(下一节讨论)。
在更新显示和复制文件后,我通过调用ConsoleProgressBar类的Update方法来更新进度条。
一旦循环结束并且文件复制结束,我再把ForegroundColor设置回其原来的颜色,并且把光标位置设置到控制台窗口的最下面一行,并且使之再次可见。
五、 移动控制台中的一个区域
MoveBufferArea方法允许我指定控制台窗口内的一个区域(或缓冲区),然后指定一组坐标来移动它。我想把文件名列表显示到一个滚动列表中,而同时还能维持头部信息及控制台窗口顶部的进度栏。一旦我把一个文件名打印到控制台中的最后一行,我就停止更新rowIndex变量并开始使用 MoveBufferArea方法。
MoveBufferArea使用了六个参数:
· 第一个参数指定你想选择区域的左边缘。
· 第二个参数指定你的缓冲区区域的最上边一行。
· 第三和第四个参数指定你的缓冲区区域的宽度和高度。
· 最后两个参数指定你想把你的缓冲区移往的区域的左边缘和最上边一行。
Console.MoveBufferArea(0, _
BufferSourceTopLine, _
Console.WindowWidth, _
Console.WindowHeight - BufferSourceTopLine, _
0, _
BufferDestinationTopLine)
这段代码告诉MoveBufferArea方法从第0列和第BufferSourceTopLine(一个常量,值为8)行开始。然后,它把缓冲区区域宽度设置为等于控制台窗口的宽度并且把缓冲区区域高度设置为等于控制台窗口高度和文件名列表的最上面一行(BufferSourceTopLine)之差。最后两个参数指定我的缓冲区区域的目标位置为第0列和第BufferDestinationTopLine(定义为常数7)行。
用更简单的描述来说就是,该代码通过最后一个名字选择在列表中的第二个文件名并且把该缓冲区往上移动一行,有效地删除了最上面的文件名并且为底部的下一个文件名留出了空间。
六、 ConsoleProgressBar类
我创建了ConsoleProgressBar类来处理初始化和更新进度条的细节问题。其构造器使用了一个参数—MaximumValue:
Public Sub New(ByVal MaximumValue As Long)
m_length = Console.WindowWidth - 10
m_left = 7
m_right = m_left + m_length + 1
m_progressBarRow = 1
m_messageBarRow = m_progressBarRow + 1
m_percentPosition = 4
m_maximumValue = MaximumValue
m_currentValue = 0
Initialize()
End Sub
我硬编码了一些值,并且基于这些硬编码值计算其它值。在本文中,我构造的这个类很小,但是你可以扩展这个构造器以便再加入其它参数—使得进度条更具配置性。
在初始化所有的成员变量以后,我调用Initialize方法,它又调用InitializePercentComplete, InitializeProgressBar和InitializeMessageBar方法。这些方法的任务并不多;它们仅打印一个百分号,一组表示进度条结束的方括号,以及该进度条的最大值和最小值。