15 thg 10, 2010

GZipStream và Strings




 
Nén và giải nén sử dụng Gzip là một trong những vấn đề phổ biến ở bất cứ một ngôn ngữ lập trình nào. Bài viết này sẽ giới thiệu một cách làm hiệu qủa và dễ hiểu
Bạn có một static class trong class này chứa một số đối tượng trong .Net framework mà bạn sử dụng, được mô tả qua bảng sau:
Phần tử
Công dụng
byte[] arrays
Là mảng byte chứa các kí tự trong xâu được lưu dưới dạng byte do đó dễ dàng kiểm soát bởi GZip hơn.
MemoryStream
Stream trong C# có thể được dùng như các filter và cũng có thể giống như một nơi lưu trữ. Chúng ta sử dụng MemoryStream để lưu trữ
GZipStream
Chúng ta sử dụng GzipStream như một filter, với các lựa chọn CompressionMode.Compress CompressionMode.Decompre. Nó phụ thuộc vào MemoryStream
 Các bạn có thể hiểu qua ví dụ dưới đây, Bạn có một class trong đó chứa 2 phương thức static. Các phương thức này rất hữu dụng để nén và giải nén một xâu. Để rõ ràng và dễ hình dung hơn bạn hãy nhìn vào biểu đồ và các ví dụ bên dưới.
using System.IO;
using System.IO.Compression;
 
// thực hiện các hàm dưới đây để có thể nén và giải nén xâu
class CompressionUtil
{
    private static byte[] StringToBytes(string stringValue)
    {
        int length = stringValue.Length;
        byte[] resultBytes = new byte[length];
        for (int i = 0; i < length; i++)
        {
            resultBytes[i] = (byte)stringValue[i];
        }
        return resultBytes;
    }
 
    private static string BytesToString(byte[] byteValues, int numberBytes)
    {
        char[] buffer = new char[numberBytes];
        for (int i = 0; i < numberBytes; i++)
        {
            buffer[i] = (char)byteValues[i];
        }
        return new string(buffer);
    }  
//nén xâu truyền vào và trả về một xâu. Tên tham số là stringValue
//Trả về dữ liệu được nén.
    public static string CompressString(string stringValue)
    {
        // chuyển xâu thành màng byte
        byte[] byteArray = StringToBytes(stringValue);      
        // sử dụng MemoryStream để lưu GZipStream
        using (MemoryStream memoryStream = new MemoryStream())
        {
      //ghi dữ liệu vào bộ nhớ qua GzipStream.
            using (GZipStream gZipStream = new GZipStream(memoryStream,
                CompressionMode.Compress))
            {
                gZipStream.Write(byteArray, 0, byteArray.Length);
            }
            // chuyển memory stream về mảng byte.
            byteArray = memoryStream.ToArray();
        }
        //Chuyển mảng  byte về string và return.
        return BytesToString(byteArray, byteArray.Length);
    }
 
    public static string DecompressString(string stringValue)
    {
        // chuyển string thành mảng byte
        byte[] byteArray = StringToBytes(stringValue);
        int byteCount = 0;
        //sử dụng MemoryStream để lưu GZipStream
        using (MemoryStream memoryStream = new MemoryStream(byteArray))
        {
         // Giải nén dữ liệu bằng cách ghi GZipStream
            using (GZipStream gZipStream = new GZipStream(memoryStream,
                CompressionMode.Decompress))
            {
                byteArray = new byte[byteArray.Length];
                byteCount = gZipStream.Read(byteArray, 0, byteArray.Length);
            }
        }
        // Trả vể mảng byte trong string form
        return BytesToString(byteArray, byteCount);
    }
}

 

Chúng ta sử dụng 2 hàm trên như sau:
class Program
{
    static void Main(string[] args)
    {
        // Đọc một file từ ổ đĩa 
        string fileContents;
        using (StreamReader reader = new StreamReader("line-test.txt"))
        {
            fileContents = reader.ReadToEnd();
        }
        // Cho biết dung lượng file
        Console.WriteLine("Original size: " + fileContents.Length.ToString());
        // Tạo ra file nén cho file đó
        string zipped = CompressionUtil.CompressString(fileContents);
        // cho biết dung lượng file nén
        Console.WriteLine("Zipped size: " + zipped.Length.ToString());
      
      // Tạo ra xâu được giải nén
        string unzipped = CompressionUtil.DecompressString(zipped);
 
        // hiển thị
        Console.WriteLine("Unzipped size: " + unzipped.Length.ToString());
 
        if (unzipped == fileContents)
        {
          // Nếu dòng này được hiển thị thì ctrinh của bạn chay tốt
            Console.WriteLine("Compression correct");
        }
    }
}
 Bạn có thể sử dụng StringBuilde để chuyển một mảng byte thành một xâu, nhưng cách làm này khá chậm . Cách làm trên sử dụng mảng char. Bạn có thể thấy sự khác biệt khi sử dụng StringBuilder và BytesToString trong biểu đồ dưới đây:
  
  
 Thân.

Không có nhận xét nào:

Đăng nhận xét