检查文件的前 n 个字节是否在 Powershell 中是特定的
Check if the first n bytes of a file are specific in Powershell
如何将文件中的字节与值的文字数组进行比较?
$path = "C:\BinaryFile.bin"
$bytes = Get-Content -LiteralPath $path -Encoding byte -TotalCount 4 -ReadCount 4
if ($bytes -eq [0 1 2 3]) { # How to compare to expected bytes?
Write-Output "OK: $bytes"
}
PowerShell 没有用于序列相等的 built-in 运算符,但您可以编写自己的小实用函数来满足此目的:
function Test-ArrayEquals
{
param([array]$ReferenceArray, [array]$DifferenceArray)
if($ReferenceArray.Length -ne $DifferenceArray.Length){
# not same length, not equal
return $false
}
for($i = 0; $i -lt $ReferenceArray.Length; $i++){
if($ReferenceArray[$i] -ne $DifferenceArray[$i]){
# two aligned array members were found to not be equal
return $false
}
}
# we reached the end, array values must be equal
return $true
}
现在您可以:
if (Test-ArrayEquals -ReferenceArray @(0, 1, 2, 3) -DifferenceArray $bytes) {
# looks good!
}
也许 compare-object。没有输出意味着相等。准确顺序的同步窗口 0。
$path = 'file'
[byte[]](0..3) | set-content $path -Encoding Byte
$bytes = Get-Content $path -Encoding byte -TotalCount 4
if (! (compare-object $bytes 0,1,2,3 -syncwindow 0)) {
"OK: $bytes"
}
或者进行字符串比较:
if ("0 1 2 3" -eq $bytes) {
"OK: $bytes"
}
数组可以通过Compare-Object
进行比较。这将读取文件的前四 (4) 个字节并将其与文字数组进行比较。
在 Windows PowerShell 5.1 中:
Compare-Object `
-ReferenceObject (Get-Content -Path '.\file.txt' -Encoding Byte -TotalCount 4) `
-DifferenceObject @(97,100,115,102) -SyncWindow 0
在 PowerShell 核心中 6.x+:
Compare-Object `
-ReferenceObject (Get-Content -Path '.\file.txt' -AsByteStream -TotalCount 4) `
-DifferenceObject @(97,100,115,102) -SyncWindow 0
其他答案提供了有用的解决方案,适用于 any 类型的数组。
这是一个适用于您的情况的快捷方式,将数组作为字符串进行比较 ,利用 PowerShell 字符串化 数组的方式(请参阅下面的 限制 ):
if ("$bytes" -eq '1 2 3' ) { # Be sure to use *decimal* values
Write-Output "OK: $bytes"
}
限制:
PowerShell 通过用空格连接数组的(字符串化的)元素来对数组进行字符串化;例如,$bytes = 0x1, 0x2, 0xA; "$bytes"
变成一个具有逐字值 1 2 10
的字符串(请注意如何使用数字的 十进制 表示)。
因此,通过数组的 (PowerShell) 字符串表示比较数组仅在 满足以下条件的情况下 稳健地 有效:
元素具有明确的字符串表示(通常:.NET 原始类型,例如数字和字符串)
没有元素的字符串表示有 嵌入 个空格。
如果元素是 strings 并且您想要区分大小写 比较它们 ,请使用 -ceq
代替 -eq
LINQ-based解法
此解决方案基于 System.Linq.Enumerable.SequenceEqual()
,适用于所有类型。
请注意需要[byte[]]
强制转换 - 它会创建强类型 副本 输入数组(它们本身是 [object[]]
类型) - 按顺序为了使方法调用起作用:
if ([Linq.Enumerable]::SequenceEqual([byte[]] $bytes, [byte[]] (1, 2, 3))) {
Write-Output "OK: $bytes"
}
警告:在这种情况下无关紧要,但通常值得注意的是,此方法在术语方面更严格 element-by-element 比较比由 Compare-Object
和 -eq
运算符执行的 PowerShell 相等性测试:值得注意的是,字符串元素的大小写比较 敏感 默认。如果您选择 [object[]]
作为上面的转换 - 以避免需要创建数组的 副本 - 具有相同值的数字只有在它们是完全相同的类型;值得注意的是,数组文字 1, 2, 3
创建一个 [object[]]
数组,其中包含 [int]
个值,而不是 [byte]
个值。
从好的方面来说,LINQ 的使用有可能比 Compare-Object
解决方案执行得更好 - 有关详细信息,请参阅 的底部部分。
如何将文件中的字节与值的文字数组进行比较?
$path = "C:\BinaryFile.bin"
$bytes = Get-Content -LiteralPath $path -Encoding byte -TotalCount 4 -ReadCount 4
if ($bytes -eq [0 1 2 3]) { # How to compare to expected bytes?
Write-Output "OK: $bytes"
}
PowerShell 没有用于序列相等的 built-in 运算符,但您可以编写自己的小实用函数来满足此目的:
function Test-ArrayEquals
{
param([array]$ReferenceArray, [array]$DifferenceArray)
if($ReferenceArray.Length -ne $DifferenceArray.Length){
# not same length, not equal
return $false
}
for($i = 0; $i -lt $ReferenceArray.Length; $i++){
if($ReferenceArray[$i] -ne $DifferenceArray[$i]){
# two aligned array members were found to not be equal
return $false
}
}
# we reached the end, array values must be equal
return $true
}
现在您可以:
if (Test-ArrayEquals -ReferenceArray @(0, 1, 2, 3) -DifferenceArray $bytes) {
# looks good!
}
也许 compare-object。没有输出意味着相等。准确顺序的同步窗口 0。
$path = 'file'
[byte[]](0..3) | set-content $path -Encoding Byte
$bytes = Get-Content $path -Encoding byte -TotalCount 4
if (! (compare-object $bytes 0,1,2,3 -syncwindow 0)) {
"OK: $bytes"
}
或者进行字符串比较:
if ("0 1 2 3" -eq $bytes) {
"OK: $bytes"
}
数组可以通过Compare-Object
进行比较。这将读取文件的前四 (4) 个字节并将其与文字数组进行比较。
在 Windows PowerShell 5.1 中:
Compare-Object `
-ReferenceObject (Get-Content -Path '.\file.txt' -Encoding Byte -TotalCount 4) `
-DifferenceObject @(97,100,115,102) -SyncWindow 0
在 PowerShell 核心中 6.x+:
Compare-Object `
-ReferenceObject (Get-Content -Path '.\file.txt' -AsByteStream -TotalCount 4) `
-DifferenceObject @(97,100,115,102) -SyncWindow 0
其他答案提供了有用的解决方案,适用于 any 类型的数组。
这是一个适用于您的情况的快捷方式,将数组作为字符串进行比较 ,利用 PowerShell 字符串化 数组的方式(请参阅下面的 限制 ):
if ("$bytes" -eq '1 2 3' ) { # Be sure to use *decimal* values
Write-Output "OK: $bytes"
}
限制:
PowerShell 通过用空格连接数组的(字符串化的)元素来对数组进行字符串化;例如,$bytes = 0x1, 0x2, 0xA; "$bytes"
变成一个具有逐字值 1 2 10
的字符串(请注意如何使用数字的 十进制 表示)。
因此,通过数组的 (PowerShell) 字符串表示比较数组仅在 满足以下条件的情况下 稳健地 有效:
元素具有明确的字符串表示(通常:.NET 原始类型,例如数字和字符串)
没有元素的字符串表示有 嵌入 个空格。
如果元素是 strings 并且您想要区分大小写 比较它们 ,请使用 -ceq
代替 -eq
LINQ-based解法
此解决方案基于 System.Linq.Enumerable.SequenceEqual()
,适用于所有类型。
请注意需要[byte[]]
强制转换 - 它会创建强类型 副本 输入数组(它们本身是 [object[]]
类型) - 按顺序为了使方法调用起作用:
if ([Linq.Enumerable]::SequenceEqual([byte[]] $bytes, [byte[]] (1, 2, 3))) {
Write-Output "OK: $bytes"
}
警告:在这种情况下无关紧要,但通常值得注意的是,此方法在术语方面更严格 element-by-element 比较比由 Compare-Object
和 -eq
运算符执行的 PowerShell 相等性测试:值得注意的是,字符串元素的大小写比较 敏感 默认。如果您选择 [object[]]
作为上面的转换 - 以避免需要创建数组的 副本 - 具有相同值的数字只有在它们是完全相同的类型;值得注意的是,数组文字 1, 2, 3
创建一个 [object[]]
数组,其中包含 [int]
个值,而不是 [byte]
个值。
从好的方面来说,LINQ 的使用有可能比 Compare-Object
解决方案执行得更好 - 有关详细信息,请参阅