Powershell为什么这两个json内容之间存在差异?
我有两个Powershell为什么这两个json内容之间存在差异?,json,powershell,Json,Powershell,我有两个Byte[]类型的变量(我选择这种类型是为了满足特定的需要,所以需要保留),它们声明为: $first = New-Object Byte[] 32 $second = New-Object Byte[] 32 我初始化了这两个变量的每个指数 现在,我创建了一个hashtable$List1,如下所示: $List1=@{"First" = $first; "Second" = $second} 我使用以下语法创建json文件: $List1 | ConvertTo-Json | S
Byte[]
类型的变量(我选择这种类型是为了满足特定的需要,所以需要保留),它们声明为:
$first = New-Object Byte[] 32
$second = New-Object Byte[] 32
我初始化了这两个变量的每个指数
现在,我创建了一个hashtable$List1
,如下所示:
$List1=@{"First" = $first; "Second" = $second}
我使用以下语法创建json文件:
$List1 | ConvertTo-Json | Set-Content -Path $jsonFile1
这是第一个json文件内容:
{
"First": {
"value": [
210,
195,
131,
176,
88,
154,
57,
37,
2,
75,
182,
190,
156,
43,
113,
199,
63,
25,
109,
92,
220,
91,
219,
252,
113,
68,
202,
12,
147,
194,
36,
177
],
"Count": 32
},
"Second": {
"value": [
238,
225,
12,
172,
134,
94,
42,
204,
27,
78,
39,
166,
229,
111,
143,
254
],
"Count": 16
}
}
{
"First": [
133,
231,
19,
173,
60,
50,
105,
68,
38,
109,
99,
155,
2,
188,
216,
9,
8,
225,
203,
15,
167,
8,
188,
76,
192,
154,
183,
194,
1,
122,
143,
137
],
"Second": [
27,
3,
57,
67,
155,
145,
181,
194,
250,
10,
65,
90,
41,
230,
243,
196
]
}
然后我将第一个json文件读入一个临时变量,如下所示:
$tempHash = Get-Content -Path $jsonFile1 -Raw| ConvertFrom-Json
$List2 = @{"First" = $tempHash.First.value; "Second"= $tempHash.Second.value}
$List2 | ConvertTo-Json | Set-Content -Path $jsonFile2
由于$tempHash
是一个PSCustomObject
,我创建了一个新的哈希表$List2
,如下所示:
$tempHash = Get-Content -Path $jsonFile1 -Raw| ConvertFrom-Json
$List2 = @{"First" = $tempHash.First.value; "Second"= $tempHash.Second.value}
$List2 | ConvertTo-Json | Set-Content -Path $jsonFile2
我使用它创建第二个json文件,如下所示:
$tempHash = Get-Content -Path $jsonFile1 -Raw| ConvertFrom-Json
$List2 = @{"First" = $tempHash.First.value; "Second"= $tempHash.Second.value}
$List2 | ConvertTo-Json | Set-Content -Path $jsonFile2
这是第二个json文件内容:
{
"First": {
"value": [
210,
195,
131,
176,
88,
154,
57,
37,
2,
75,
182,
190,
156,
43,
113,
199,
63,
25,
109,
92,
220,
91,
219,
252,
113,
68,
202,
12,
147,
194,
36,
177
],
"Count": 32
},
"Second": {
"value": [
238,
225,
12,
172,
134,
94,
42,
204,
27,
78,
39,
166,
229,
111,
143,
254
],
"Count": 16
}
}
{
"First": [
133,
231,
19,
173,
60,
50,
105,
68,
38,
109,
99,
155,
2,
188,
216,
9,
8,
225,
203,
15,
167,
8,
188,
76,
192,
154,
183,
194,
1,
122,
143,
137
],
"Second": [
27,
3,
57,
67,
155,
145,
181,
194,
250,
10,
65,
90,
41,
230,
243,
196
]
}
我使用相同的语法创建这两个json文件。那么,为什么它们的结构不同呢
[编辑]
我想,区别就在于这种语法:
$List1=@{"First" = $first; "Second" = $second}
因为字节[]
类型变量不能作为简单的整数[]
类型变量使用。
纠正我
[编辑]
因此,Byte[]
type变量有两个不同的键。
保存字节值的实际数组的“value”,以及
“Count”,它保存字节[]
变量中的元素数。
但是,当我们调用Byte[]
类型变量时,如下所示:
$first
这是Byte[]
类型,我们只获得“value”键下列出的值。“count”键下的值永远不会显示在控制台中,但它会以某种方式传递给哈希表
还有一点需要注意。如果我使用:
$List2 = @{"First" = $tempHash.First; "Second"= $tempHash.Second}
那么,我必须使用:
$List2.First.Value #to get the value of the "First" key
这让我感到不舒服,因为对于$List1
哈希表,我只需要使用:
$List1.First #to get the value of the "First" key.
[解决方法]
我创建了一个hastable$List
作为原始hashtable,如下所示,仅供一次使用:
然后,我从上面的原始$jsonFile
创建了两个hastable$List1
和$List2
,如下所示
$tempHash = Get-Content -Path $jsonFile -Raw| ConvertFrom-Json
$List1 = @{"First" = $tempHash.First; "Second" = tempHash.Second}
$List2 = @{"First" = $tempHash.First; "Second" = tempHash.Second}
它帮助我在引用它们的键和值时保持一致性
现在,我使用
#to fetch the values of the "First" keys of both hashtables.
$List1.First.value #and
$List2.First.value
类似地,我对哈希表$List1
和$List2
的“Second”键执行相同的操作
#to fetch the values of the "Second" keys of both hashtables.
$List1.Second.value #and
$List2.Second.value
[编辑]
它原来是我的Powershell版本中的一个bug,由下面的@mklement0测试。
完美的解决方案是按照@mklement0的指示使用以下语法:
# Ensure that the input array is constructed without the extra [psobject] wrapper.
$First = [Byte[]]::new(32)
$Second = [Byte[]]::new(32)
更改此项:
$List2 = @{"First" = $tempHash.First.value; "Second"= $tempHash.Second.value}
为此:
$List2 = @{"First" = $tempHash.First; "Second"= $tempHash.Second}
这将维护值
和计数
结构。在测试时,它还保持了value
部分中值的顺序
编辑
为了增强您的解决方法,您可以加入此步骤,以便无需使用
。value
:
$firstValues = [byte[]]($tempHash.First.value)
$secondValues = [byte[]]($tempHash.Second.value)
$List1 = @{"First" = $firstValues; "Second" = $secondValues}
$List2 = @{"First" = $firstValues; "Second" = $secondValues}
自包含测试脚本
$jsonFile1 = "jsonFile1.json"
$jsonFile2 = "jsonFile2.json"
$first = New-Object Byte[] 32
$second = New-Object Byte[] 16
foreach($i in 0..($first.COunt -1)){
$first[$i] = Get-random -minimum 1 -maximum 254
}
foreach($i in 0..($second.COunt -1)){
$second[$i] = Get-random -minimum 1 -maximum 254
}
$List = @{"First" = $first; "Second" = $second}
$List | ConvertTo-Json | Set-Content -Path $jsonFile1
$tempHash = Get-Content -Path $jsonFile1 -Raw | ConvertFrom-Json
$firstValues = [byte[]]($tempHash.First.value)
$secondValues = [byte[]]($tempHash.Second.value)
$List1 = @{"First" = $firstValues; "Second" = $secondValues}
$List2 = @{"First" = $firstValues; "Second" = $secondValues}
- 从v5.1开始,第一个
调用的结果是Windows PowerShell中的一个怪癖:生成的Json应该具有ConvertTo Json
和first
直接包含数组,而不是具有Second
和value
属性的对象,包含数组的Count
。值
- 这种行为已经被证实;它可能会在Windows PowerShell中得到修复,也可能不会得到修复(从v5.1起仍然存在)。
产生:$a=新对象字节[]2@{a=$a}|转换为Json-压缩
- PowerShell Core v6.0.1中的
-正常{“a”:[0,0]}
- Windows PowerShell v5.1中的{“a”:{“value”:[0,0],“Count”:2}已损坏
- PowerShell Core v6.0.1中的
- 这种行为已经被证实;它可能会在Windows PowerShell中得到修复,也可能不会得到修复(从v5.1起仍然存在)。
- 在你的例子中,正是使用
触发了这个怪癖新对象
- 最有可能的原因是:;但是,请注意,上述问题在PowerShell Core中也没有得到解决,但上面链接的修复程序解决了此上下文中的问题
解决方法: 在脚本/会话开始时,运行:
Remove-TypeData System.Array
这将从所有数组对象中删除过时的ETS提供的.Count
属性,这使得[psobject]
-包装对象(如新对象返回的对象)的问题消失-有关说明,请参阅我的
更麻烦的解决方法:
如果确保输入数组的-is[psobject]
不再报告true,则问题就会消失,这可以通过以下方法之一完成:
- [PSv5+]:
$First=[Byte[]]::new(32)
-使用表达式而不是命令可以解决问题,因为它不会创建额外的、不可见的[psobject]
包装器
- [PSv4-]:
$First=(新对象字节[]32).psobject.BaseObject
-显式绕过额外的[psobject]
包装可以解决问题
简化示例(PSv5+,但很容易适应早期版本;省略了文件操作,因为它们是问题的附带原因):
以上结果现在正确地产生(没有具有值
和计数
属性的无关对象):
将此JSON字符串重新转换为对象现在可以正常工作:
# Re-convert: $tempObj.First then *directly* contains the input array
# (there is no .Value property anymore).
$tempObj = $json | ConvertFrom-Json
# Construct a new hashtable...
$List2 = @{ First = $tempObj.First }
# ... and convert it to JSON.
$List2 | ConvertTo-Json
结果是与上面相同的JSON字符串。。即使在将$temphash
中的值强制转换为[byte[]]
时,json输出也是不同的。步骤中似乎发生了一些可疑的事情,这解决了问题。然而,当我们调用Byte[]类型的变量时,比如:$first,它是Byte[]类型的,我们只得到“value”键下列出的值。“count”键下的值永远不会显示在控制台中,但它会以某种方式传递到哈希表中。还要注意的一点是:如果我使用$List2=@{“First”=$tempHash.First;“Second”=$tempHash.Second}现在,我必须使用$List2.First.value到g