Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.01.2011, 01:05   #1
Ultr164
 
Регистрация: 04.01.2011
Сообщений: 4
По умолчанию Запись байтов из массива

Всем привет, вот уже два дня колупаюсь с байтами файлов. Пытаюсь писать байты, что бы файл как можно меньше весил (Хаффман). Но как не пытаюсь в любой HEX редакторе вижу непонятные наборы байтов. Если пишу данные как текстовый файл, то вес слишком большой, а байты записать так и не получилось.
Код:
procedure SaveFileThread.Execute;
var
  FileStreamOpen: File;
  FileStreamSave: File of Byte;
  ByteArray: Array[0..1024] of Byte;
  I, X, SizeOfFile, Count: Integer;
  Block: String;
  Last, Num, Key, Drw, Spc: Integer;
begin
  Action := 'Сжимаем файл';
  Synchronize(UpdateAction);

  AssignFile(FileStreamOpen, FilePathOpen);
  Reset(FileStreamOpen, 1);
  AssignFile(FileStreamSave, FilePathSave);
  Rewrite(FileStreamSave);
  SizeOfFile := FileSize(FileStreamOpen);

  X := 0;
  Num := 0;
  Drw := 2;
  Spc := 3;

  while not Eof(FileStreamOpen) do
  begin
    BlockRead(FileStreamOpen, ByteArray, 1024, Count);
    for I := 0 to Count do
    begin
      Key := ByteArray[I];
      if Num = 0 then
      begin
        Last := Key;
        Num := Num + 1;
      end
      else
        if Last = Key then
          Num := Num + 1
        else
        begin
          if Num = 1 then
          begin
            Write(FileStreamSave, Alternative[Last]);
            Write(FileStreamSave, Spc);
          end
          else
          begin
            Write(FileStreamSave, Alternative[Last]);
            Write(FileStreamSave, Drw);
            Write(FileStreamSave, Num);
            Write(FileStreamSave, Spc);
          end;
          Last := Key;
          Num := 1;
        end;
    end;
    X := X + 1024;
    Progress := Trunc(X / SizeOfFile * 100);
    Synchronize(UpdateProgress);
  end;
  CloseFile(FileStreamOpen);
  CloseFile(FileStreamSave);

  Action := 'Файл успешно сжат';
  Synchronize(UpdateAction);

  Synchronize(Ending);

  endthread(0);
end;
На скрине красным выделил то, куда я хочу писать нули и единицы.
Ultr164 вне форума Ответить с цитированием
Старый 05.01.2011, 01:26   #2
XeruH
Форумчанин
 
Регистрация: 17.09.2010
Сообщений: 229
По умолчанию

А Что ты хочешь видеть там где у тебя выделено красным? 0 и 1.. так и пиши туда 0 или 1 )
Правильно заданный вопрос - половина ответа!
XeruH вне форума Ответить с цитированием
Старый 05.01.2011, 02:07   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

0 и 1 это биты скорее а не байты.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.01.2011, 04:17   #4
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Цитата:
Сообщение от Ultr164 Посмотреть сообщение
вижу непонятные наборы байтов
непонятные не значит неправильные )

Прога подсчитывает, сколько раз подряд встречается очередной байт (Key) из входного файла, и пишет в выходной файл соответсвующий байт из массива Alternative[Key], за которым идёт байт со значением [3], если Key повторился 1 раз, или байты [2], [Num], [3], если Key повторился Num раз.

Довольно-таки странный алгоритм, с ещё более странной реализацией, которая ломается, если Key повторится более чем 255 раз, или если Key будет повторятся на границе блока в 1024 байт, но во всяком случае в файл записывается всё верно.

Что действительно непонятно, так это при чём тут Хаффман )
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 05.01.2011, 11:54   #5
Ultr164
 
Регистрация: 04.01.2011
Сообщений: 4
По умолчанию

По Хаффманскому алгоритму я получаю альтернативы для каждого байта (для этого разумеется считаю частоту вхождения всех байтов) и потом хочу записать эти последовательности нулей и единиц в файл. Но как я уже не пробовал, новый файл получаю либо намного больше прежнего, либо точно такого же размера
Ultr164 вне форума Ответить с цитированием
Старый 05.01.2011, 16:01   #6
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

просто надо работать на уровне бит, а у тебя вся работа идёт с байтами (8 бит).

Хаффманские альтернативы, насколько я помню, могут быть от 2 до, скажем, 32 бит каждая. Вот и надо их записывать как цепочку бит, а не как целый байт каждый раз.

Могу только порекомендовать выкинуть всё, что уже написано, и начать заново. Сделать процедуру записи цепочки бит в файл. И вызывать её по мере поступления данных, передавая ей указатель на биты и количество бит, которое надо записать (от 1 до 32, например).

Процедура эта, по мере накопления бит, будет сбрасывать их в файл, и тут уже работа будет с байтами.

Возможно, проще окажется преобразовывать биты в строку, и работать со строкой бит (каждый символ строки будет или '0' или '1'), добавляя новые биты в конец строки простым сложением строк. Это менее эффективно, зато наглядно.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 05.01.2011, 16:26   #7
Ultr164
 
Регистрация: 04.01.2011
Сообщений: 4
По умолчанию

Можно пример кода для работы с битами? Если есть
Ultr164 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Получение данных переменной ввиде массива байтов chertovich Общие вопросы Delphi 3 18.12.2010 21:51
Запись массива в функцию RobinVit Общие вопросы C/C++ 9 02.05.2010 23:43
Данные из буфера обмена в виде массива байтов eda Microsoft Office Excel 10 12.08.2009 17:00
Запись массива в txt yura-cat Помощь студентам 5 20.10.2008 23:54
запись Массива в БД Chepa БД в Delphi 4 26.12.2006 18:58