powershell二进制文件比较

powershell二进制文件比较,powershell,powershell-2.0,Powershell,Powershell 2.0,全部,, 有一个应用程序生成它的导出转储。我需要编写一个脚本,将前几天的转储与最新的转储进行比较,如果它们之间有差异,我必须对移动和删除这类内容进行一些基本操作。 我已尝试找到一种合适的方法,我尝试的方法是: $var\u com=diff(获取内容D:\local\prodexport2-编码字节)(获取内容D:\local\prodexport2-编码字节) 我也尝试了Compare-Object cmdlet。我注意到内存使用率非常高,几分钟后我最终收到一条消息System.OutOfMe

全部,, 有一个应用程序生成它的导出转储。我需要编写一个脚本,将前几天的转储与最新的转储进行比较,如果它们之间有差异,我必须对移动和删除这类内容进行一些基本操作。 我已尝试找到一种合适的方法,我尝试的方法是:
$var\u com=diff(获取内容D:\local\prodexport2-编码字节)(获取内容D:\local\prodexport2-编码字节)
我也尝试了Compare-Object cmdlet。我注意到内存使用率非常高,几分钟后我最终收到一条消息
System.OutOfMemoryException
。你们中有人做过类似的事吗?。请想一想。 有一个帖子提到了一个比较,我不知道该怎么做。 提前谢谢各位
Osp

您可以使用fc.exe。它带有窗户。以下是您将如何使用它:

fc.exe /b d:\local\prodexport2 d:\local\prodexport1 > $null
if (!$?) {
    "The files are different"
}

另一种方法是比较文件的MD5哈希:

$Filepath1 = 'c:\testfiles\testfile.txt'
$Filepath2 = 'c:\testfiles\testfile1.txt'

$hashes = 
foreach ($Filepath in $Filepath1,$Filepath2)
{
 $MD5 = [Security.Cryptography.HashAlgorithm]::Create( "MD5" )
 $stream = ([IO.StreamReader]"$Filepath").BaseStream
 -join ($MD5.ComputeHash($stream) | 
 ForEach { "{0:x2}" -f $_ })
 $stream.Close()
 }

if ($hashes[0] -eq $hashes[1])
  {'Files Match'}

不久前,我写了一篇关于:

您可以通过以下方式使用它:

文件等于c:\temp\test.html c:\temp\test.html


散列(如MD5)需要遍历整个文件才能进行散列计算。此脚本在看到缓冲区中的差异时立即返回。它使用比本机PowerShell更快的LINQ来比较缓冲区。

对于PowerShell 4,您可以使用本机commandlet来执行此操作:

function CompareFiles {
    param(
    [string]$Filepath1,
    [string]$Filepath2
    )
    if ((Get-FileHash $Filepath1).Hash -eq (Get-FileHash $Filepath2).Hash) {
        Write-Host 'Files Match' -ForegroundColor Green
    } else {
        Write-Host 'Files do not match' -ForegroundColor Red
    }
}
PS C:>比较文件。\20131104.csv。\20131104-copy.csv

文件匹配

PS C:>比较文件。\20131104.csv。\20131107.csv

文件不匹配

如果希望以编程方式大规模使用此函数,可以轻松修改上述函数以返回$true或$false值


编辑 看到这个答案后,我只想提供更大比例的版本,它只返回truefalse

function CompareFiles 
{
    param
    (
        [parameter(
            Mandatory = $true,
            HelpMessage = "Specifies the 1st file to compare. Make sure it's an absolute path with the file name and its extension."
        )]
        [string]
        $file1,

        [parameter(
            Mandatory = $true,
            HelpMessage = "Specifies the 2nd file to compare. Make sure it's an absolute path with the file name and its extension."
        )]
        [string]
        $file2
    )

    ( Get-FileHash $file1 ).Hash -eq ( Get-FileHash $file2 ).Hash
}

你需要知道哪些字节是不同的,或者只是今天的文件和昨天不一样吗?只需要知道它们是否不同。正如你所引用的,我需要知道这些文件是否相同。看看答案。它标记为C#,但由于它是.NET,因此可以将其移植到PowerShell语法。最简单的方法是首先比较文件大小-如果它们不同,您已经有了答案。谢谢。我尝试将此代码与相对路径一起使用(因此在Powershell
cd某处
中,然后是
$FilePath1='testfile.txt'
),但StreamReader没有拾取Powershell对文件夹的更改,而是认为它是相对于我的主文件夹的。修复方法是使用
$Filepath1=Get Item'testfile.txt'
,然后Powershell将正确的绝对路径传递给StreamReader。Powershell的Get FileHash函数(现在)可用,并且做同样的事情更简单。我可能倾向于不使用
if(!$?)
并将其替换为
if($lastextcode-eq 0)
。检查和所有答案。对于不同的文件,这是非常慢的,因为它会打印所有差异(为空)。fc似乎不支持不打印输出。人们可以使用“fc/a/b”,它可能会试图减少输出,但对我来说并没有太大的影响。只是出于好奇,分配给$null是否有帮助,例如,
$null=fc.exe…
?在性能方面,您的例程与@ericnils相比如何?当你在一个函数中使用它时,它可能会被一个
foreach
调用,这个函数包含很多大小不同的文件,你的函数是否比4.0
get FileHash
?@CodeMaverick更优化,这应该正是他所说的原因。它不必读取两个完整的文件,除非它们是相同的。这是理想的解决方案,我建议将
$BYTES\u TO\u READ
设置为高于8的值。在我的系统上,每次迭代读取8字节的速度非常慢。我不知道最好的值是什么,但将缓冲区大小增加到32768(32KB)肯定会使文件比较快。我意识到将
$BYTES\u更改为\u READ
是不够的,因为在循环中
位转换器
调用只比较缓冲区的前8个字节(=one
Int64
)。经过深思熟虑,我决定使用第二个内部循环,该循环迭代字节数组并单独比较每个字节。这相当快,而且比ultra-slow
compare object
cmdlet快得多。不幸的是,正如Herzube所指出的,当前的实现给出了完全错误的答案,因为每32768个字节中只有8个字节被实际比较。您好,欢迎使用stackoverflow,谢谢您的回答。虽然这段代码可能会回答这个问题,但是你能考虑为你解决的问题增加一些解释,以及你是如何解决的?这将帮助未来的读者更好地理解你的答案并从中学习。
function CompareFiles 
{
    param
    (
        [parameter(
            Mandatory = $true,
            HelpMessage = "Specifies the 1st file to compare. Make sure it's an absolute path with the file name and its extension."
        )]
        [string]
        $file1,

        [parameter(
            Mandatory = $true,
            HelpMessage = "Specifies the 2nd file to compare. Make sure it's an absolute path with the file name and its extension."
        )]
        [string]
        $file2
    )

    ( Get-FileHash $file1 ).Hash -eq ( Get-FileHash $file2 ).Hash
}
if ( (Get-FileHash c:\testfiles\testfile1.txt).Hash -eq (Get-FileHash c:\testfiles\testfile2.txt).Hash ) {
   Write-Output "Files match"
} else {
   Write-Output "Files do not match"
}