2012-07-13 124 views
2

我有错误,而解压缩错误与解压/压缩误差

“的输入是不是一个有效的Base-64字符串,因为它含有非基本64字符,两个以上的填充字符,或一个非填充字符中的空白字符。“

压缩好但不解压缩。我看过很多其他有相同问题的例子,我觉得我遵循所说的内容,但是当我解压缩时仍然没有获得任何东西。这里的压缩和解压缩方法:

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

     mStream.Position = 0; 

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

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


    public static string DecompressData(string compressedData) 
    { 
     byte[] gZipBffr = Convert.FromBase64String(compressedData); 
     using (var mStream = new MemoryStream()) 
     { 
      int dataLength = BitConverter.ToInt32(gZipBffr , 0); 
      mStream.Write(gZipBffr , 4, gZipBffr .Length - 4); 

      var buffer = new byte[dataLength]; 

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

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

string s = CompressData(s2.Tostring()); 

其中s2为键入的XElement 串pH值= DecompressData(流2)); 其中stream2是类型字符串..在数据库中它存储在nvarchar类型列 这里,同时压缩和删除根标记。

首次将XML就像 皮特 2012年3月24日 百分比 33.3 下一次另一名学生的数据被添加到现有的XML,在这里每次在压缩的同时,我们有删除父标签。

 <student> 
     <data> 
     <name>peet</name> 
     <date>3/24/2012</date> 
     <field>Percent</field> 
     <new>33.3</new> 
     <old>10</old> 
     </data> 
    <data> 
     <name>raaz</name> 
     <date>3/24/2011</date> 
     <field></field> 
     <new>33.3</new> 
     <old>10</old> 
    </data> 
     <data> 
     <name>arya</name> 
     <date>3/24/2010</date> 
     <field></field> 
     <new>33.3</new> 
     <old>10</old> 
    </data> 
     </student> 
+0

几件事情:1:(迂腐,抱歉) - 你有一个错字这里:'Buffer.BlockCopy(BitConverter.GetBytes(bffer.Length),0,gZipBuffer,0,4) ;'应该是'Buffer.BlockCopy(BitConverter.GetBytes(gZipBuffer.Length),0,gZipBuffer,0,4);'我想。 2:你传递的是什么被压缩 - 我只是采取你的方法,并做了这个'Console.WriteLine(DecompressData(CompressData(“Hello”)))',我打印出你好,没有错误。 – kmp 2012-07-13 05:10:19

+0

这里我压缩和解压XML数据,在未来想添加更多的数据,之前添加到现有的一个先解压缩到XML和添加新的数据再次压缩它。前2次更改它工作正常,但当我添加第三实时解压缩失败 – GANI 2012-07-13 05:19:25

+0

也许你可以将带有XML参数的调用添加到问题中?例如,它可以更容易地计算出问题所在。 – kmp 2012-07-13 05:24:41

回答

2

我觉得你的DecompressData方法是不完全正确 - 这将是适合于小尺寸,但是当数据在它得到不止一个学生数据我想是因为你没有足够的空间分配会失败你的缓冲区。

一个可行的方法是这样的(可能比做阵列副本更好,你真的应该让缓冲区大于100,但我做得很小,以确保它循环几次以确保它可以工作正确):

public static string DecompressData(string compressedData) 
{ 
    byte[] gZipBffr = Convert.FromBase64String(compressedData); 
    using (var mStream = new MemoryStream()) 
    { 
     mStream.Write(gZipBffr, 4, gZipBffr.Length - 4);  
     mStream.Position = 0; 

     var bytes = new byte[0]; 
     using (var gZipStream = new GZipStream(mStream, 
               CompressionMode.Decompress)) 
     { 
      byte[] buffer = new byte[100]; 
      int read; 
      while((read = gZipStream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       var newBytes = new byte[bytes.Length + read]; 
       Array.Copy(bytes, newBytes, bytes.Length); 
       Array.Copy(buffer, 0, newBytes, bytes.Length, read); 
       bytes = newBytes; 
      } 
     } 
     return Encoding.UTF8.GetString(bytes); 
    }   
} 

如果我正确你是存储在数据库中(nvarchar列编码的压缩XML基地64理解你),你想要把它拿出来,将其解压缩,一个节点添加到它,压缩它并放回去。

为了帮助你一点(也许)这里是一些代码,我怀孕了,做这个过程(除DATABSE电话 - 你可以看到你可以把那些):

private static void UpdateStudent(XElement data, int studentId) 
{ 
    XDocument student = ReadStudent(studentId); 
    student.Root.Add(data); 
    SaveStudent(studentId, student); 
} 

private static void SaveStudent(int studentId, XDocument data) 
{ 
    string compressed = CompressData(data.ToString()); 
    SaveStudentData(studentId, compressed); 
} 

private static XDocument ReadStudent(int studentId) 
{ 
    string data = GetStudentFromDatabase(studentId); 
    XDocument ret; 
    if (string.IsNullOrEmpty(data)) 
    { 
     ret = XDocument.Parse("<student></student>"); 
    } 
    else 
    { 
     string decompressed = DecompressData(data).TrimEnd('\0'); 
     ret = XDocument.Parse(decompressed); 
    } 
    return ret; 
} 

// These two methods would query the database but for demo, just store 
// in a static member 
private static string GetStudentFromDatabase(int studentId) 
{ 
    return _data; 
} 

private static void SaveStudentData(int studentId, string data) 
{ 
    _data = data; 
} 

private static string _data; 

然后调用我做:

UpdateStudent(XElement.Parse("<data><name>peet</name><date>3/24/2012</date><field>Percent</field><new>33.3</new><old>10</old></data>"), 1); 
UpdateStudent(XElement.Parse("<data><name>raaz</name><date>3/24/2011</date><field></field><new>33.3</new><old>10</old></data>"),1); 
UpdateStudent(XElement.Parse("<data><name>arya</name><date>3/24/2010</date><field></field><new>33.3</new><old>10</old></data> "), 1); 
+0

非常感谢它.. – GANI 2012-07-14 07:18:14