Как проверить скопированный файл на VB.Net - PullRequest
0 голосов
/ 28 марта 2019

В настоящее время я работаю с приложением, которое переносит миллионы изображений (.TIF) с одного 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 Ответ

1 голос
/ 28 марта 2019

Обычный способ сделать это - хэшировать файлы. 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

Кроме того, я настоятельно рекомендую запускать задачи параллельно, так как вы обрабатываете много файлов.Используйте Parallel.ForEach, если вы используете .NET Framework 4 +.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...