我正在尝试序列化我的powershell对象并通过tcp连接发送它们。因此,我不能将XML读或写到文件中,因为对于应该只在内存中发生的事情来说,这是浪费时间。我从这里获得了一个很棒的convertfrom-xml脚本,似乎可以工作:http://poshcode.org/2294
为了减小我的包的大小,并且可能通过隐藏提供一点点的安全性,我尝试在对象传输时使用gzipstream压缩它们。我也试过deflestream。他们似乎都不适合我。
$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)
行失败,表示缺少根元素。因此,我尝试直接从$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>
然后我尝试了一些其他的事情来让它工作,包括用deflateststream替换gzipstream,刷新$gz,从$gz读取到第三个流。它们都不能帮助初始的-1或截断我的xml。是什么导致了这两个问题?
我刚刚为您尝试了这个,没有截断所包含的文件
http://wannemacher.us/?p = 225
我的原始文件是39689字节,这使它成为475(我只是复制了对象块一遍又一遍,并关闭了对象标签)。
下面是使用内存流的例子-
$inFile = "C:UsersandyDesktopcompressit.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()