[英]Powershell Why the difference between the two json contents?
我有兩個Byte[]
類型的變量(我為特定需要選擇了這個類型,所以需要保留它。)聲明為:
$first = New-Object Byte[] 32
$second = New-Object Byte[] 32
並且,我將兩個變量的每個索引都初始化了。
現在,我創建了一個哈希表$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
}
}
然后我將第一個json文件讀入臨時變量,如下所示:
$tempHash = Get-Content -Path $jsonFile1 -Raw| ConvertFrom-Json
由於$tempHash
是PSCustomObject
,我創建一個新的哈希表$List2
,如下所示:
$List2 = @{"First" = $tempHash.First.value; "Second"= $tempHash.Second.value}
我用它來創建第二個json文件,如下所示:
$List2 | ConvertTo-Json | Set-Content -Path $jsonFile2
這是第二個json文件內容:
{
"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[]
類型變量不能作為簡單的integer[]
類型變量。 糾正我。
[編輯]
因此,事實證明Byte[]
類型變量有兩個不同的鍵。 “value”保存字節值的實際數組,“Count”保存Byte[]
變量中的元素數。 但是,當我們調用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
作為原始哈希表,如下所示, 僅限一次使用 :
$List | ConvertTo-Json | Set-Content -Path $jsonFile
然后,我從上面的原始$jsonFile
創建了兩個hastables $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
類似地,我為hashtables $List1
和$List2
“Second”鍵執行相同操作。
#to fetch the values of the "Second" keys of both hashtables.
$List1.Second.value #and
$List2.Second.value
[編輯]
事實證明這是我的Powershell版本中的一個錯誤,如下面的@ mklement0所示。 完美的解決方案是使用@ mklement0指示的下面的語法:
# Ensure that the input array is constructed without the extra [psobject] wrapper.
$First = [Byte[]]::new(32)
$Second = [Byte[]]::new(32)
從v5.1開始,第一個ConvertTo-Json
調用的結果是Windows PowerShell中的一個怪癖 :生成的JSON應該具有First
和Second
直接包含數組,而不是具有value
和Count
屬性的對象 ,其value
包含數組。
$a = New-Object Byte[] 2; @{ a = $a } | ConvertTo-Json -Compress
$a = New-Object Byte[] 2; @{ a = $a } | ConvertTo-Json -Compress
產量:
{"a":[0,0]}
- 好的。 {"a":{"value":[0,0],"Count":2}}
在Windows PowerShell v5.1中 - BROKEN。 在你的情況下, 使用New-Object
會觸發怪癖 。
解決方法 :
在腳本/會話開始時,運行:
Remove-TypeData System.Array
這將從所有數組對象中刪除過時的ETS提供的.Count
屬性,這會使[psobject]
包裝對象(例如由New-Object
返回)的問題消失 - 有關解釋,請參閱我的這個答案 。
更麻煩的解決方法 :
如果確保-is [psobject]
不再為輸入數組報告為true,則問題就會消失,這可以通過以下方式之一完成:
[PSv5 +]: $First = [Byte[]]::new(32)
- 使用表達式而不是命令會使問題消失,因為它不會創建額外的,不可見的[psobject]
包裝器。
[PSv4-]: $First = (New-Object Byte[] 32).psobject.BaseObject
- 顯式繞過額外的[psobject]
包裝使問題消失。
簡化示例 (PSv5 +,但很容易適應早期版本;文件操作省略,因為它們是問題的偶然):
# Ensure that the input array is constructed without the extra [psobject] wrapper.
$First = [Byte[]]::new(2)
# Construct a hashtable...
$List1 = @{ First = $first }
# ... and convert it to JSON:
($json = $List1 | ConvertTo-Json)
上面現在正確地產生( 沒有帶有value
和count
屬性的無關對象):
{
"First": [
0,
0
]
}
現在可以按預期方式將此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字符串相同。
改變這個:
$List2 = @{"First" = $tempHash.First.value; "Second"= $tempHash.Second.value}
對此:
$List2 = @{"First" = $tempHash.First; "Second"= $tempHash.Second}
這將保持value
和count
結構。 在測試時,它還保持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}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.