Davood
Davood

Reputation: 5645

Convert binary to string not works

I created a simple program.

I create a string and compress it by following methods and store it in a binary data field type in sql server 2008 (binary(1000) field type).

When I read that binary data and result string is true like original string data with the same length and data but when I want to decompress it it gave me an error.

I use this method to get bytes:

 System.Text.ASCIIEncoding.ASCII.GetBytes(mystring)

And this method to get string:

System.Text.ASCIIEncoding.ASCII.GetString(binarydata)

In hard code in VS2012 editor, result string works fine, but when I read it from sql it gives me this error in first line of decompression method:

 The input is not a valid Base-64 string as it contains a
 non-base 64 character, more   than two padding characters, 
 or a non-white space character among the padding characters.

What's wrong with my code? These two strings are same but

string test1=Decompress("mystring");

...this method works fine but this gave me that error and can not decompress retrieved string

string temp=System.Text.ASCIIEncoding.ASCII.GetString(get data from sql) ;
string test2=Decompress(temp);

The comparing these string do not shows any deference

int result = string.Compare(test1, test2); // result=0

My compression method:

   public static string Compress(string text)
   {
       byte[] buffer = Encoding.UTF8.GetBytes(text);
       var memoryStream = new MemoryStream();
       using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
       {
           gZipStream.Write(buffer, 0, buffer.Length);
       }

       memoryStream.Position = 0;

       var compressedData = new byte[memoryStream.Length];
       memoryStream.Read(compressedData, 0, compressedData.Length);

       var gZipBuffer = new byte[compressedData.Length + 4];
       Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
       Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
       return Convert.ToBase64String(gZipBuffer);
   }

My decompression method:

   public static string Decompress(string compressedText)
   {
       byte[] gZipBuffer = Convert.FromBase64String(compressedText);
       using (var memoryStream = new MemoryStream())
       {
           int dataLength = BitConverter.ToInt32(gZipBuffer, 0);
           memoryStream.Write(gZipBuffer, 4, gZipBuffer.Length - 4);

           var buffer = new byte[dataLength];

           memoryStream.Position = 0;
           using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
           {
               gZipStream.Read(buffer, 0, buffer.Length);
           }

           return Encoding.UTF8.GetString(buffer);
       }
   }

Upvotes: 0

Views: 617

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127563

The most likely issue is the way you are getting the string from the SQL binary filed.

Currently (I guess, you have not showed how you stored or retrieved your data from SQL)

  • Compress : Text -> UTF8.GetBytes -> compress -> base64 string-> Send to Sql (transformed to binary)
  • Decompress: Binary -> String representation of binary -> base64 decode -> decompress -> UTF8.GetString

Your issue is the String representation of binary step is not the same as the Send to Sql (transformed to binary). If you are storing this as a varbinary you should be returning the byte array from compress and decompress should take in a byte array.

public byte[] string Compress(string text)
{
  //Snip
}

public static string Decompress(byte[] compressedText)
{
   //Snip
}

this changes your process to

  • Compress : Text -> UTF8.GetBytes -> compress -> Send to Sql
  • Decompress: Binary -> decompress -> UTF8.GetString

Upvotes: 2

Related Questions