/// <summary> /// 通过一个文件流创建哈夫曼解码器 /// </summary> /// <param name="f"></param> public HuffmanDecoder(FileStream f) { source = f; Int32 i; byte[] buffer = new byte[4]; f.Read(buffer, 0, 4); //读取文件头标记,获取编码表的长度 i = Codec.ReadInt(buffer, 4); buffer = new byte[i]; //读取文件头中编码表 f.Read(buffer, 0, i); codex = new HuffmanCodex(buffer); //反序列化哈夫曼编码 }
public static double AverageCodeLength(Analyzer a, HuffmanCodex c) { long length = 0; long sum = 0; foreach (int i in a.Value.Values) { sum += i; } foreach (Block i in c.Codex.Keys) { length += c.Codex[i].length * a.Value[i]; } return(1.0 * length / sum); }
/// <summary> /// 点击压缩 /// </summary> private void Compress_Click(object sender, EventArgs e) { FileStream fs = File.OpenRead(InputFile.Text); try { StatusInfo.Clear(); Compress.Enabled = false; StatusText = "分析文件......"; StatusText = "加载哈夫曼编码编码......"; Codex.Analyzer a = new Codex.Analyzer(fs); Codex.HuffmanCodex h = new Codex.HuffmanCodex(a); StatusText = "写入哈夫曼编码......"; fs.Position = 0; Codex.HuffmanEncoder en = new Codex.HuffmanEncoder(h, fs); FileStream target = File.OpenWrite(OutputFile.Text); target.SetLength(0); target.WriteByte((Byte)Codex.Block.BlockSize); //文件第一位写块大小 en.WriteCodexToStream(target); StatusText = "写入压缩文件......"; var buffer = en.ReadToEnd(); target.Write(buffer, 0, buffer.Length); StatusText = "写入完成."; StatusText = "压缩率:" + (100.0 * target.Length / fs.Length) + '%'; StatusText = "平均编码长度:" + Codex.Debug.AverageCodeLength(a, h) + "位"; StatusText = "字典大小:" + Codex.Block.BlockSize + "字节"; StatusText = "压缩文件头长度:" + h.Length + "字节"; target.Close(); } catch (DataMisalignedException) { MessageBox.Show("文件长度不能够均分到每个块中", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } fs.Close(); Compress.Enabled = true; }
/// <summary> /// 通过已生成的哈夫曼编码和要编码的数据流创建编码器 /// </summary> /// <param name="codex">哈夫曼编码表</param> /// <param name="s">要编码的字符流</param> public HuffmanEncoder(HuffmanCodex codex, Stream s) { this.codex = codex; this.source = s; }