const int size = 32; //size < 256 public static int Packing(string inputFilePath) { //открываем упаковываемый файл FileOperation InputFile; if (File.Exists(inputFilePath)) { InputFile = new FileOperation(inputFilePath, true); } else { return(-1); } //создаем таблицу частот int bytesRead; byte[] buf = new byte[size]; FrequencyTable frequency = new FrequencyTable(); while ((bytesRead = InputFile.ReadFile(buf, size)) > 0) { for (int i = 0; i < bytesRead; i++) { frequency.Add(buf[i]); } } //строим бинарное дерево и получаем таблицу кодов BinaryTree tree = new BinaryTree(frequency); Dictionary <byte, short[]> codeTable = tree.GetCodeTable(frequency); //открываем файлы, пишем таблицу частот InputFile.Reset(); FileOperation outputFile = new FileOperation(inputFilePath + ".pac", false); outputFile.WriteFile(new byte[] { 0 }, 1); //резерв места под число пустых бит в конце for (short i = 0; i < frequency.Length; i++) //записываем таблицу частот { outputFile.WriteFile(BitConverter.GetBytes(frequency[i]), sizeof(long)); } //упаковываем int outPos = 0; //текущий индекс в выходном массиве в _битах_ byte[] outBuf = new byte[32]; //выходной массив bytesRead = InputFile.ReadFile(buf, size); while (bytesRead > 0) { for (byte i = 0; i < bytesRead; i++) { byte value = buf[i]; for (byte t = 0; t < codeTable[value].Length; t++) //длина массива для каждого символа получаемого из buf { outBuf[outPos / 8] |= (byte)(codeTable[value][t] * Math.Pow(2, 7 - outPos % 8)); outPos++; if (outPos >= 32 * 8) { outputFile.WriteFile(outBuf, 32); outPos = 0; Array.Clear(outBuf, 0, 32); //запись в файл } } } bytesRead = InputFile.ReadFile(buf, size); } if (outPos > 0) //запись оставшихся бит { outputFile.WriteFile(outBuf, outPos / 8 + ((outPos % 8 > 0) ? 1 : 0)); } outputFile.Reset(); outputFile.WriteFile(new byte[] { (byte)((8 - outPos % 8) % 8) }, 1); //записываем количество пустых бит в конце outputFile.CloseFile(); InputFile.CloseFile(); return(1); }