如何在VB.Net上验证复制的文件

时间:2019-03-28 14:35:36

标签: .net vb.net visual-studio-2017

我目前正在做一个将数百万个图像(.TIF)从一个NAS迁移到另一个NAS的应用程序,并且我想进行一次验证,使我可以检查文件是否被正确复制。

我的复制方式是使用执行此操作的函数

Public Function CopyFiles(ByVal origin As String, ByVal copiedFile As String)
    Try
        'Check if file exists
        If File.Exists(copiedFile) = False Then
            My.Computer.FileSystem.CopyFile(origin, copiedFile)
            Log("File copied  succsessfully")
        Else
            Log("File already exists")
        End If
        Return True
    Catch ex As Exception
        Log("Error while copying file " + origin.ToString + " Error:" + ex.ToString)
    End Try
    Return False

我确实具有此文件比较功能:

Private Function FileCompare(ByVal file1 As String, ByVal file2 As String) As Boolean
    'Compara byte a byte que los archivos sean iguales.
    'ACTUALMENTE NO SE UTILIZA
    Dim file1byte As Integer
    Dim file2byte As Integer
    Dim fs1 As FileStream
    Dim fs2 As FileStream
    Try

        ' Determine if the same file was referenced two times.
        If (file1 = file2) Then
            ' Return 0 to indicate that the files are the same.
            Return True
        End If

        ' Open the two files.
        fs1 = New FileStream(file1, FileMode.Open)
        fs2 = New FileStream(file2, FileMode.Open)

        ' Check the file sizes. If they are not the same, the files
        ' are not equal.
        If (fs1.Length <> fs2.Length) Then
            ' Close the file
            fs1.Close()
            fs2.Close()

            ' Return a non-zero value to indicate that the files are different.
            Return False
        End If

        ' Read and compare a byte from each file until either a
        ' non-matching set of bytes is found or until the end of
        ' file1 is reached.
        Do
            ' Read one byte from each file.
            file1byte = fs1.ReadByte()
            file2byte = fs2.ReadByte()
        Loop While ((file1byte = file2byte) And (file1byte <> -1))

        ' Close the files.
        fs1.Close()
        fs2.Close()

        ' Return the success of the comparison. "file1byte" is
        ' equal to "file2byte" at this point only if the files are 
        ' the same.
        If ((file1byte - file2byte) = 0) Then
            'Log("******* Archivo Comparado correctamente= " + file1.ToString + "  " + file2.ToString + " *******")
            Return True
        Else
            Log("******* ERROR: al comparar archivos: " + file1.ToString + "  " + file2.ToString + " *******")
            Return False
        End If


    Catch ex As Exception
        Log("******* ERROR, excepcion al comparar archivos: " + file1.ToString + " VS " + file2.ToString + " " + ex.ToString.ToUpper + " *******")
        Return False
    End Try
    Return True
End Function

但是开始对每个单个图像逐字节比较时花了太长时间,所以我在考虑其他方法来验证文件是否已正确复制。

到目前为止,我已经实现的是我检查复制的文件是否存在,但这并不能保证我没有复制任何问题。

所以我的想法是:

  • 创建一个打开和关闭文件的功能,只是检查它是否可以打开。

  • 创建一个比较原始文件和复制文件大小的函数,但是我不知道是否有可能复制文件的大小相同但有错误。

  • 只需留下一个函数来验证复制的文件是否存在,因为到目前为止,在我所有的测试中,复制的图像都没有问题。

1 个答案:

答案 0 :(得分:1)

执行此操作的通常方法是对文件进行哈希处理。 MD5是用于此目的的通用哈希函数,它比迭代每个字节并进行比较要快。将您的代码更改为以下内容:

Private Function FileCompare(ByVal file1 As String, ByVal file2 As String) As Boolean
    'Compara byte a byte que los archivos sean iguales.
    'ACTUALMENTE NO SE UTILIZA
    Dim file1byte As Integer
    Dim file2byte As Integer
    Dim fs1 As FileStream
    Dim fs2 As FileStream
    Try

        ' Determine if the same file was referenced two times.
        If (file1 = file2) Then
            ' Return 0 to indicate that the files are the same.
            Return True
        End If

        ' Open the two files.
        fs1 = New FileStream(file1, FileMode.Open)
        fs2 = New FileStream(file2, FileMode.Open)

        ' Check the file sizes. If they are not the same, the files
        ' are not equal.
        If (fs1.Length <> fs2.Length) Then
            ' Close the file
            fs1.Close()
            fs2.Close()

            ' Return a non-zero value to indicate that the files are different.
            Return False
        End If

        Try
            Dim file1Hash as String = hashFileMD5(file1)
            Dim file2Hash as String = hashFileMD5(file2)

            If file1Hash = file2Hash Then
                Return True
            Else
                Return False
            End If

        Catch ex As Exception
            Return False
        End Try


    Catch ex As Exception
        Log("******* ERROR, excepcion al comparar archivos: " + file1.ToString + " VS " + file2.ToString + " " + ex.ToString.ToUpper + " *******")
        Return False
    End Try
    Return True
End Function
Private Function hashFileMD5(ByVal filepath As String) As String
    Using reader As New System.IO.FileStream(filepath, IO.FileMode.Open, IO.FileAccess.Read)
        Using md5 As New System.Security.Cryptography.MD5CryptoServiceProvider
            Dim hashBytes() As Byte = md5.ComputeHash(reader) 
            Return System.Text.Encoding.Unicode.GetString(hashBytes) 
        End Using
    End Using
End Function

此外,强烈建议您在处理许多文件时并行运行任务。如果您使用的是.NET Framework 4+,请使用Parallel.ForEach