我目前正在做一个将数百万个图像(.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
但是开始对每个单个图像逐字节比较时花了太长时间,所以我在考虑其他方法来验证文件是否已正确复制。
到目前为止,我已经实现的是我检查复制的文件是否存在,但这并不能保证我没有复制任何问题。
所以我的想法是:
创建一个打开和关闭文件的功能,只是检查它是否可以打开。
创建一个比较原始文件和复制文件大小的函数,但是我不知道是否有可能复制文件的大小相同但有错误。
只需留下一个函数来验证复制的文件是否存在,因为到目前为止,在我所有的测试中,复制的图像都没有问题。
答案 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
。