Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 当直接从get content分配或检索数组时,为什么数组的行为会有所不同_Arrays_Powershell_Formatting - Fatal编程技术网

Arrays 当直接从get content分配或检索数组时,为什么数组的行为会有所不同

Arrays 当直接从get content分配或检索数组时,为什么数组的行为会有所不同,arrays,powershell,formatting,Arrays,Powershell,Formatting,有件事我不明白 定义变量时: $v = [byte]2, [byte]3 并检查其类型: $v.getType().name $f.getType().name 我明白了 然后我格式化$v: '{0} {1}' -f $v 哪张照片 2 3 现在,如果我得到文件的前两个字节: $f = (get-content 'xyz.txt' -encoding byte -readCount 2 -totalCount 2) 并检查其类型: $v.getType().name $f.getT

有件事我不明白

定义变量时:

$v = [byte]2, [byte]3
并检查其类型:

$v.getType().name
$f.getType().name
我明白了

然后我格式化
$v

'{0} {1}' -f $v
哪张照片

2 3
现在,如果我得到文件的前两个字节:

$f = (get-content 'xyz.txt' -encoding byte -readCount 2 -totalCount 2)
并检查其类型:

$v.getType().name
$f.getType().name
我得到了与以前相同的类型:
Object[]

但是,与
$v
不同,我无法格式化
$f

'{0} {1}' -f $f
我收到错误消息错误格式化字符串:索引(基于零)必须大于或等于零且小于的大小,尽管数组的长度为2:

$f.length
返回

2
我不明白这是为什么,请解释一下。

  • 行为应被视为
    -f
    操作符中的错误
    ;从v7.1开始出现,并在中报告;它不影响具有数组操作数的其他运算符,例如
    -split
    -in

  • 解决方法是将
    $f
    强制转换为
    [array]
    ,或者,如果可以创建数组的副本,
    @($f)

注意:使用
@()
,-
…-@($f)
-作为注释-是更简单的选项,但请注意,使用
@()
涉及到克隆(创建数组的浅层副本),而在本例中的
[array]
强制转换则没有

另一种方法是将
[array]
强制转换应用为类型约束(通过将其放置在
$f=…
赋值的左侧):

注:

  • 在PowerShell[Core]v6+中,必须使用
    -AsByteStream
    代替
    -Encoding Byte

  • 如果省略
    -ReadCount 2
    ,也可以避免该问题,但请注意,这会降低命令的性能,因为随后会逐个发出字节;也就是说,使用
    -ReadCount 2-TotalCount 2
    会发出一个作为一个整体的2字节数组的单个对象,而只
    -TotalCount 2
    会将单个字节逐个发送到管道,在这种情况下,PowerShell引擎本身会在
    [object[]中收集这些字节
    分配的数组

  • 请注意,在这种情况下,直接将
    @()
    应用于命令-
    @(获取内容…
    -)将不起作用,因为
    @()
    ,由于参数组合
    -ReadCount 2-TotalCount 2
    ,接收一个恰好是整个数组的单个输出对象,因此将该单个对象包装到另一个数组中。这将产生一个单元素数组,其元素是字节的原始2元素数组;有关
    @(…)
    工作原理的更多信息,请参阅


背景信息:

问题是在
Get Content-ReadCount
返回的每个数组周围都有一个不可见的
[psobject]
包装器(在本例中只有一个),这意外地导致传递给
-f
$f
数组无法被识别

请注意,PowerShell的其他基于阵列的运算符(如
-in
-replace
)不受影响

可以通过两种方式绕过包装器:

  • $f.psobject.BaseObject

  • 转换到
    [array]
    ,如顶部所示

注:

  • 通常,cmdlet生成的输出对象与PowerShell代码生成的输出不同,通常具有不可见的
    [psobject]
    包装器;大多数情况下,它们都是良性的,因为PowerShell通常只关心被包装的.NET对象,而不关心包装器,但有时会出现问题,例如在本例中-有关问题的讨论以及它所体现的其他上下文,请参阅

  • 为了测试给定对象是否有
    [psobject]
    包装器
    ,请使用
    -is[psobject]
    ;e、 g:

$var=1
$var-is[psobject]#->$false
$var=写入输出1
$var-由于使用了cmdlet,因此为[psobject]#->$true。
#您还可以直接测试命令输出。
(写入输出1)-是否为[psobject]#->$true
'abc' > xyz.txt

[array] $f = (get-content 'xyz.txt' -encoding byte -readCount 2 -totalCount 2)

'{0} {1}' -f $f