我正在尝试序列化我的powershell对象并通过tcp连接发送它们。因此,我无法将我的XML读取或写入文件,因为这样做会浪费时间,只能在内存中发生。我从这里获得了一个很棒的convertfrom-xml脚本,似乎可以工作:http://poshcode.org/2294
为了保持我的数据包的大小,并且可能仅通过默默无闻提供一点点安全性,我试图使用gzipstream在旅行时压缩对象。我也试过deflatestream。他们似乎都不适合我。
$o = ""|select x,y,z,a
$o.x = 3
$o.y = "hello"
$o.z = [datetime]::now
$o.a = 1..9
$xml = $o | convertto-xml
$mem = new-object system.io.memorystream
$gz = new-object system.io.compression.gzipstream($mem, [system.io.compression.compressionmode]::compress)
$xml.save($gz)
$bytes = $mem.toarray()
$gz.close()
$mem.close()
这部分成功地给了我一个看似压缩的字节数组。
$mem = new-object system.io.memorystream(,$bytes)
$gz = new-object system.io.compression.gzipstream($mem, [system.io.compression.compressionmode]::decompress)
$gz.flush()
$xml = new-object xml
$xml.load($gz)
$o = $xml | convertfrom-xml
$gz.close()
$mem.close()
此部分在$xml.load($gz)
行失败,表示缺少Root元素。我因此尝试直接从$ gz读取,并获得-1开始(我认为意味着流的结束?),然后在第一个-1之后立即获得以下数据:
<?xml version="1.0"?>
<Objects>
<Object Type="System.Management.Automation.PSCustomObject">
<Property Name="x" Type="System.Int32">3</Property>
<Property Name="y" Type="System.String">hello</Property>
<Property Name="z" Type="System.DateTime">16/08/2014 11:43:48 PM</Property>
<Property Name="a" Type="System.Object[]">
<Property Type="System.Int32">1</Property>
<Property Type="System.Int32">2</Property>
<Property Type="System.Int32">3</Property>
<Property Type="System.Int32">4</Property>
<Property Type="System.Int32">5</Property>
<Property Type="System.Int32">6</Property>
<Property Type="System.Int32">7</Property>
<Property Type="System.Int32">8</Property>
<Property Type="System.Int32">9</Property>
</Property>
</Object>
然后,我尝试了其他一些工作,包括用deflatestream替换gzipstream,刷新$ gz,以及从$ gz读取第三个流。他们都没有帮助初始-1或截断我的xml。是什么导致了这两个问题?
我怀疑我的主要问题是我对溪流的基本熟悉程度。
答案 0 :(得分:0)
我刚试过这个,没有截断封闭的文件
我的原始文件是39689字节,这使它成为475(我只是反复复制该对象块并关闭对象标记)。
以下是使用内存流调整的示例 -
$inFile = "C:\Users\andy\Desktop\compressit.txt"
$input = New-Object System.IO.FileStream $inFile, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read)
$buffer = New-Object byte[]($input.Length)
$byteCount = $input.Read($buffer, 0, $input.Length)
$input.Close()
$output = New-Object System.IO.MemoryStream
$gzipStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress)
$gzipStream.Write($buffer, 0, $buffer.Length)
$gzipStream.Close()
# Show the results
$output.ToArray() | Set-Content -Path ($inFile + '.gz') -Encoding Byte
$output.Close()