2012-07-13 121 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