我正在尝试开发一个简单的批量复制程序,它以指定的时间间隔轮询给定文件夹中的文件。
代码看起来很完美。我的输出提供了一个很好的递归文件列表,但是当我根据列表实际移动它们时,我扫描的每个文件都被锁定。我已经尝试过垃圾收集,处理,在某些点退出潜艇,在某些点进行调试......
请查看我的代码。调用MoveFile时,一切都被锁定。
Imports System
Imports System.IO
Public Structure FileStructure
Dim Enumerator As Integer
Dim SPath As String
Dim DPath As String
Dim Name As String
Dim FileSize As Long
Dim IsFile As Short
Dim SourceFullName As String
Dim DestFullName As String
End Structure
Public Class StagingDriveCoordinator
Dim FilesScanned As FileStructure()
Dim ScanCount As Integer = -1
Private Sub ScanAll(ByVal sourcePath As String, ByVal destinationPath As String)
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(sourcePath)
' ---------------------- Create the appropriate directories --------------------------------
' Create source path
If Not System.IO.Directory.Exists(sourcePath) Then
System.IO.Directory.CreateDirectory(sourcePath)
End If
' If the destination folder doesn't exist then create it
If Not System.IO.Directory.Exists(destinationPath) Then
System.IO.Directory.CreateDirectory(destinationPath)
End If
' ------------------------------------------------------------------------------------------
Dim AddSize As Integer = 0
'Figure out how much to resize the array this iteration of ScanAll
If FilesScanned IsNot Nothing Then
AddSize = FilesScanned.Count + sourceDirectoryInfo.GetFileSystemInfos.Length
Else
AddSize = sourceDirectoryInfo.GetFileSystemInfos.Length
End If
'Resize the array
Array.Resize(FilesScanned, AddSize)
For Each FileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
ScanCount += 1
FilesScanned(ScanCount).Enumerator = ScanCount
FilesScanned(ScanCount).SPath = sourcePath.ToString
FilesScanned(ScanCount).DPath = destinationPath.ToString
FilesScanned(ScanCount).Name = FileSystemInfo.Name.ToString
If TypeOf FileSystemInfo Is System.IO.FileInfo Then
FilesScanned(ScanCount).FileSize = DirectCast(FileSystemInfo, FileInfo).Length
FilesScanned(ScanCount).IsFile = 1
Else
FilesScanned(ScanCount).FileSize = 9223372036854775807
FilesScanned(ScanCount).IsFile = 0
End If
FilesScanned(ScanCount).SourceFullName = System.IO.Path.Combine(sourcePath, FileSystemInfo.Name).ToString
FilesScanned(ScanCount).DestFullName = System.IO.Path.Combine(sourcePath, FileSystemInfo.Name).ToString
txtOutput.Text += FilesScanned(ScanCount).Enumerator & vbTab & FilesScanned(ScanCount).SourceFullName & vbNewLine
If FilesScanned(ScanCount).IsFile = 0 Then
'Debug
txtOutput.Text += vbNewLine & "Recursively scanning subfolder " + FilesScanned(ScanCount).Name & "..." + vbNewLine + vbNewLine
'Recursively call the main scanner.
ScanAll(FilesScanned(ScanCount).SourceFullName, FilesScanned(ScanCount).DestFullName)
End If
Next
End Sub
Private Sub MoveFile(ByVal Source, ByVal Destination, ByVal filesize)
Try
File.Copy(Source, Destination, True)
txtOutput.Text += "Moving file... Source: " & Source & ". Filesize: " & filesize.ToString & vbNewLine
txtOutput.Text += "Destination: " & Destination & vbNewLine & vbNewLine
File.Delete(Source)
Catch ex As Exception
txtOutput.Text += "File " & Source & " is locked." & vbNewLine
End Try
End Sub
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
Select Case cmbPollingFrequency.SelectedItem
Case "5 Seconds"
Timer1.Interval = 5000
Case "30 Seconds"
Timer1.Interval = 30000
Case "1 Minute"
Timer1.Interval = 60000
Case "5 Minutes"
Timer1.Interval = 300000
Case "15 Minutes"
Timer1.Interval = 900000
Case "30 Minutes"
Timer1.Interval = 1800000
Case "1 Hour"
Timer1.Interval = 3600000
Case Else
MsgBox("You must select an interval.")
End Select
Timer1.Start()
End Sub
Private Sub TimerTick(sender As Object, e As EventArgs) Handles Timer1.Tick
Timer1.Stop()
txtOutput.Text += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") & vbNewLine
txtOutput.Text += "Scanning Filesystem..." + vbNewLine + vbNewLine
'Scan the file system.
ScanAll(cmbStaging.Text, cmbBackup.Text)
txtOutput.Text += vbNewLine
txtOutput.Text += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") & vbNewLine
txtOutput.Text += " ------------- Scan cycle completed. --------------- " & vbNewLine & vbNewLine
txtOutput.Text += "Sorting by filesize..." & vbNewLine & vbNewLine
' Sort the file list by size.
FilesScanned = FilesScanned.OrderBy(Function(x) x.FileSize).ToArray
txtOutput.Text += "Done." & vbNewLine & vbNewLine
txtOutput.Text += "Moving smallest files first..." & vbNewLine & vbNewLine
For Each FileElement In FilesScanned
If FileElement.IsFile > 0 Then
'file.FileSize only needed to pass size to text output
MoveFile(FileElement.SourceFullName, FileElement.DestFullName, FileElement.FileSize)
End If
Next
FilesScanned = Nothing
ScanCount = -1
Timer1.Start()
End Sub
Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
Timer1.Stop()
End Sub
End Class
答案 0 :(得分:0)
我发现了问题。 IO系统没有锁定文件。我试图将其复制到SAME目录......
FilesScanned(ScanCount).SourceFullName = System.IO.Path.Combine(sourcePath,FileSystemInfo.Name).ToString
FilesScanned(ScanCount).DestFullName = System.IO.Path.Combine(sourcePath,FileSystemInfo.Name).ToString
这应该是:
FilesScanned(ScanCount).SourceFullName = System.IO.Path.Combine(sourcePath,FileSystemInfo.Name).ToString
FilesScanned(ScanCount).DestFullName = System.IO.Path.Combine(destinationPath,FileSystemInfo.Name).ToString
一旦我改变它,一切都很完美。