简体   繁体   中英

Decompress Data Stream Component: Unknown block type. Stream might be corrupted

I am trying to decompress/deserialize a datastream that is saved within an XML file attribute. The data was compressed with Delphi's Stream.WriteComponent() method. It ultimately throws this error:

exception: System.IO.InvalidDataException: Unknown block type. Stream might be corrupted.

First I retrieve the datastream using a XML LINQ Query:

var dataStream = 
(
    from XmlNode xn in nList
    where xn?.Attributes != null 
    && xn?.Attributes["Name"].InnerText == "Columns"
    select xn.Attributes["StreamData"].InnerText
).ToList()[0x0];
if (string.IsNullOrEmpty(dataStream) { return; }

I then proceed to take the XML attributes InnerText and turn it into stream data:

var byteStream = Encoding.UTF8.GetBytes(dataStream);
var memStream = new MemoryStream
(
    byteStream,
    0,
    byteStream.Length,
    true,
    true
);

I then proceed to try and decompress the datastream:

var rslt = Decompress(stream);

And this is what the Decompress() function looks like:

public static string Decompress(MemoryStream stream)
{
    using (var uncompressed = new MemoryStream())
    using (var compressed = stream)
    using (var ds = new DeflatedStream(compressed, CompressionMode.Decompress))
    {
        ds.CopyTo(uncompressed);
        return Encoding.UTF8.GetString(uncompressed.ToArray());
    }
}

The XML file looks similar to this but not identical(it is valid xml i promise):

<?xml version="1.0" encoding="UTF-8"?>
<Item Class="Item" Name="Default" GUID="{BC0EE2E4-641F-44DA-A989-F97C58B1828D}">
  <Properties>
    <Property Class="Type" GUID="{3A6C51FB-BE2E-4DBF-B2C5-8EB7C3508529}" Name="Type" group="Item" OrderIndex="0" DecimalPlaces="2">blah</Property>
    <Property Class="Text" GUID="{1119FF79-74C6-42AF-918F-1AF485614D07}" Name="Name" inheritaction="Ignore" required="True" group="Item" OrderIndex="1" DecimalPlaces="2">blahblah</Property>
    <Property Class="Number" GUID="{AF1BC5FD-A4DD-4610-92EE-2F7D7EA4FA64}" Name="OrderIndex" systemhidden="True" OrderIndex="3" DecimalPlaces="2">0</Property>
    <Property Class="Text" GUID="{176382CA-7E00-47C2-8DD3-82A9ED4FB973}" Name="GUID" inheritaction="Ignore" systemlocked="True" systemhidden="True" OrderIndex="4" DecimalPlaces="2">{BC0EE2E4-641F-44DA-A989-F97C58B1828D}</Property>
    <Property Class="Stream" GUID="{833CB9FD-4914-4899-B757-CC9C130E6914}" Name="Columns" OrderIndex="5" DecimalPlaces="2" StreamData="VFBGMB1UcHNjeEVzdGltYXRpbmdUcmVlTGlzdENvbHVtbgZDb2x1bW4MQ2FwdGlvbi5UZXh0BgROYW1lFURhdGFCaW5kaW5nLlZhbHVlVHlwZQYGU3RyaW5nBVdpZHRoAzgBEVBvc2l0aW9uLkNvbEluZGV4AgARUG9zaXRpb24uUm93SW5kZXgCABJQb3NpdGlvbi5CYW5kSW5kZXgCAAlTaG93VW5pdHMIDUlzVW5pdHNDb2x1bW4IAABUUEYwHVRwc2N4RXN0aW1hdGluZ1RyZWVMaXN0Q29sdW1uB0NvbHVtbjIMQ2FwdGlvbi5UZXh0BgtEZXNjcmlwdGlvbhVEYXRhQmluZGluZy5WYWx1ZVR5cGUGBlN0cmluZwVXaWR0aAJsEVBvc2l0aW9uLkNvbEluZGV4AgERUG9zaXRpb24uUm93SW5kZXgCABJQb3NpdGlvbi5CYW5kSW5kZXgCAAlTaG93VW5pdHMIDUlzVW5pdHNDb2x1bW4IAABUUEYwHVRwc2N4RXN0aW1hdGluZ1RyZWVMaXN0Q29sdW1uD1RyZWVMaXN0Q29sdW1uMhNQcm9wZXJ0aWVzQ2xhc3NOYW1lBhJUY3hMYWJlbFByb3BlcnRpZXMZUHJvcGVydGllcy5BbGlnbm1lbnQuSG9yegcNdGFMZWZ0SnVzdGlmeQxDYXB0aW9uLlRleHQGBUNvbG9yFURhdGFCaW5kaW5nLlZhbHVlVHlwZQYGU3RyaW5nBVdpZHRoAiwRUG9zaXRpb24uQ29sSW5kZXgCCBFQb3NpdGlvbi5Sb3dJbmRleAIAElBvc2l0aW9uLkJhbmRJbmRleAIACVNob3dVbml0cwgNSXNVbml0c0NvbHVtbggAAFRQRjAdVHBzY3hFc3RpbWF0aW5nVHJlZUxpc3RDb2x1bW4OVHJlZUxpc3RDb2x1bW4TUHJvcGVydGllc0NsYXNzTmFtZQYSVGN4TGFiZWxQcm9wZXJ0aWVzGVByb3BlcnRpZXMuQWxpZ25tZW50LkhvcnoHDnRhUmlnaHRKdXN0aWZ5DENhcHRpb24uVGV4dAYDUXR5FURhdGFCaW5kaW5nLlZhbHVlVHlwZQYFRmxvYXQOT3B0aW9ucy5Gb290ZXIJBVdpZHRoAmQRUG9zaXRpb24uQ29sSW5kZXgCAhFQb3NpdGlvbi5Sb3dJbmRleAIAElBvc2l0aW9uLkJhbmRJbmRleAIAElN1bW1hcnlGb290ZXIuS2luZAcFc2tTdW0JU2hvd1VuaXRzCQ1Jc1VuaXRzQ29sdW1uCAAAVFBGMB1UcHNjeEVzdGltYXRpbmdUcmVlTGlzdENvbHVtbg9UcmVlTGlzdENvbHVtbjQTUHJvcGVydGllc0NsYXNzTmFtZQYSVGN4TGFiZWxQcm9wZXJ0aWVzGVByb3BlcnRpZXMuQWxpZ25tZW50LkhvcnoHDnRhUmlnaHRKdXN0aWZ5DENhcHRpb24uVGV4dAYKUHJpY2UgRWFjaBVEYXRhQmluZGluZy5WYWx1ZVR5cGUGBUZsb2F0Dk9wdGlvbnMuRm9vdGVyCQVXaWR0aAJkEVBvc2l0aW9uLkNvbEluZGV4AgYRUG9zaXRpb24uUm93SW5kZXgCABJQb3NpdGlvbi5CYW5kSW5kZXgCABJTdW1tYXJ5Rm9vdGVyLktpbmQHBXNrU3VtCVNob3dVbml0cwgNSXNVbml0c0NvbHVtbggAAFRQRjAdVHBzY3hFc3RpbWF0aW5nVHJlZUxpc3RDb2x1bW4PVHJlZUxpc3RDb2x1bW41E1Byb3BlcnRpZXNDbGFzc05hbWUGElRjeExhYmVsUHJvcGVydGllcxlQcm9wZXJ0aWVzLkFsaWdubWVudC5Ib3J6Bw50YVJpZ2h0SnVzdGlmeQxDYXB0aW9uLlRleHQGC1ByaWNlIFRvdGFsFURhdGFCaW5kaW5nLlZhbHVlVHlwZQYFRmxvYXQOT3B0aW9ucy5Gb290ZXIJBVdpZHRoAmQRUG9zaXRpb24uQ29sSW5kZXgCBxFQb3NpdGlvbi5Sb3dJbmRleAIAElBvc2l0aW9uLkJhbmRJbmRleAIAFFN1bW1hcnlGb290ZXIuRm9ybWF0Bg1bIUNVXSMsIyMwLjAwElN1bW1hcnlGb290ZXIuS2luZAcFc2tTdW0JU2hvd1VuaXRzCA1Jc1VuaXRzQ29sdW1uCAAAVFBGMB1UcHNjeEVzdGltYXRpbmdUcmVlTGlzdENvbHVtbg5HcmlkVW50c0NvbHVtbgxDYXB0aW9uLlRleHQGBVVuaXRzFURhdGFCaW5kaW5nLlZhbHVlVHlwZQYGU3RyaW5nD09wdGlvbnMuRWRpdGluZwgFV2lkdGgCMRFQb3NpdGlvbi5Db2xJbmRleAIDEVBvc2l0aW9uLlJvd0luZGV4AgASUG9zaXRpb24uQmFuZEluZGV4AgAJU2hvd1VuaXRzCA1Jc1VuaXRzQ29sdW1uCQ1Vbml0Rm9yQ29sdW1uBgNRdHkAAFRQRjAdVHBzY3hFc3RpbWF0aW5nVHJlZUxpc3RDb2x1bW4PVHJlZUxpc3RDb2x1bW4zE1Byb3BlcnRpZXNDbGFzc05hbWUGElRjeExhYmVsUHJvcGVydGllcxlQcm9wZXJ0aWVzLkFsaWdubWVudC5Ib3J6Bw50YVJpZ2h0SnVzdGlmeQxDYXB0aW9uLlRleHQGCUNvc3QgRWFjaBVEYXRhQmluZGluZy5WYWx1ZVR5cGUGBUZsb2F0Dk9wdGlvbnMuRm9vdGVyCQVXaWR0aAJkEVBvc2l0aW9uLkNvbEluZGV4AgQRUG9zaXRpb24uUm93SW5kZXgCABJQb3NpdGlvbi5CYW5kSW5kZXgCABRTdW1tYXJ5Rm9vdGVyLkZvcm1hdAYNWyFDVV0jLCMjMC4wMBJTdW1tYXJ5Rm9vdGVyLktpbmQHBXNrU3VtCVNob3dVbml0cwgNSXNVbml0c0NvbHVtbggAAFRQRjAdVHBzY3hFc3RpbWF0aW5nVHJlZUxpc3RDb2x1bW4PVHJlZUxpc3RDb2x1bW42E1Byb3BlcnRpZXNDbGFzc05hbWUGElRjeExhYmVsUHJvcGVydGllcxlQcm9wZXJ0aWVzLkFsaWdubWVudC5Ib3J6Bw50YVJpZ2h0SnVzdGlmeQxDYXB0aW9uLlRleHQGCE1hcmt1cCAlFURhdGFCaW5kaW5nLlZhbHVlVHlwZQYFRmxvYXQOT3B0aW9ucy5Gb290ZXIJBVdpZHRoAkMRUG9zaXRpb24uQ29sSW5kZXgCBRFQb3NpdGlvbi5Sb3dJbmRleAIAElBvc2l0aW9uLkJhbmRJbmRleAIAElN1bW1hcnlGb290ZXIuS2luZAcFc2tTdW0JU2hvd1VuaXRzCA1Jc1VuaXRzQ29sdW1uCAAA"/>

  </Properties>
</Item>

Since XML is a string and decompression almost certainly expects binary data as the input, then the value of the StreamData attribute must be an ASCII/string encoded representation of binary data. This could be using a simple bin-2-hex notation but from the example provided in the question, it looks more likely to be base64 or similar.

Whoever is providing the XML should be able to confirm the encoding for you.

In any event, we can be fairly certain that the StreamData has to be in a string encoded form since otherwise the binary data will contain values that will result in an invalid XML file (eg bytes with value 0 etc)

That being the case then your problem is that Encoding.UTF8.GetBytes() interprets the data it is passed simply as an array of bytes. That is, it expects that the bytes it is given are part of a valid UTF8 encoded string. It does not do any conversion from hexadecimal characters to binary bytes etc.

That is, to use a very simplistic example, if your StreamData is a string with the value "000102" then your code will currently yield a byteStream that has content consisting of 6 (six) bytes with values as follows:

StreamData :  '0' '0' '0' '1' '0' '2'
bytes      : [30][30][30][31][30][32]    (hexadecimal byte values)

When what you probably are expecting is a stream of 3 (three) bytes with values corresponding to the StreamData as follows:

StreamData : '00''01''02'
bytes      : [00][01][02]                (hexadecimal byte values)

ie you will need to properly decode the StreamData string to it's in-memory, binary representation before passing it to the Decompress() routine which is complaining currently because the binary data it is being supplied is not valid, compressed data.

You need to confirm the encoding of the binary data in StreamData and apply the appropriate decoding to obtain the binary representation of that data before passing this to the Decompress() routine, rather than the raw/original string representation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM