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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 05.07.2017, 09:12   #1
Elenik
Пользователь
 
Регистрация: 22.03.2013
Сообщений: 23
По умолчанию Непонятная проблема с TFileStream

Приветствую профессионалов!
Помогите разобраться. Выполняю кодирование и декодирование данных с помощью TFileStream. Первый код - кодирование:
Код:
    
Strm:=TFileStream.Create(SaveFile.InitialDir+edLab.Text+'.dat', fmCreate);
    try
        // данные ярлыка в record
      Strm.WriteBuffer(DataLabel, SizeOf(DataLabel));
        // данные рез-тов испытаний в record
      Strm.WriteBuffer(DataIsp, SizeOf(DataIsp));
         //
        // текстовые документы
      for n:=1 to 2 do begin
          // текст в stringList
        if n=1 then OpenText.Title:='файл результатов' else OpenText.Title:='файл отчета';
        if n=1 then InfoDoc.tDoc:=10 else InfoDoc.tDoc:=15;
        if OpenText.Execute then begin
          slDoc:=TStringList.Create;
          slDoc.LoadFromFile(OpenText.FileName);
        end;
          // кодировка и сохранение в поток
        SetLength(Buf,0); nBuf:=0;
        for i:=0 to slDoc.Count-1 do begin
          st:=slDoc[i];
          for j:=1 to Length(st) do begin
            Inc(nBuf); SetLength(Buf,nBuf);
            Buf[nBuf-1]:=(ord(st[j])+223)*3+1000;
          end;
          Inc(nBuf); SetLength(Buf,nBuf);
          Buf[nBuf-1]:=(13+223)*3+1000;
        end;
        slDoc.Free;
          // порционная запись
        if nBuf<501 then begin
          InfoDoc.colBuf:=1; InfoDoc.sizeEndBuf:=nBuf;
        end
        else begin
          InfoDoc.colBuf:=Trunc(nBuf/500)+1;
          InfoDoc.sizeEndBuf:= nBuf mod 500;
        end;
        Strm.WriteBuffer(InfoDoc, SizeOf(InfoDoc)); 
        if InfoDoc.colBuf=1 then Strm.WriteBuffer(Buf[0], SizeOf(Buf)*InfoDoc.sizeEndBuf)
        else begin
          for i:=1 to InfoDoc.colBuf-1 do
            Strm.WriteBuffer(Buf[(i-1)*500], SizeOf(Buf)*500);
          Strm.WriteBuffer(Buf[(InfoDoc.colBuf-1)*500], SizeOf(Buf)*InfoDoc.sizeEndBuf);
        end;
      end;
        // закрываем поток
    finally
      Strm.Free;
    end;
Второй код - декодирование:
Код:
  Strm:=TFileStream.Create(FileList.FileName,fmOpenRead);
  try
      // данные ярлыка
    Strm.ReadBuffer(DataLabel,SizeOf(DataLabel));
      // данные испытаний
    Strm.ReadBuffer(DataIsp,SizeOf(DataIsp));
      // текстовые документы
    for n:=1 to 2 do begin
      Strm.ReadBuffer(InfoDoc,SizeOf(InfoDoc));
      if Strm.Position+SizeOf(Buf)*(InfoDoc.colBuf-1)*500+InfoDoc.sizeEndBuf > Strm.Size then begin ShowMessage('err-'+IntToStr(n)); break; end;
      if InfoDoc.tDoc=10 then st:='_res.txt' else st:='_otch.txt';
      AssignFile(ff,MyDir+'DataResults\'+DataLabel.Izd+st); rewrite(ff);
      try
        if InfoDoc.colBuf=1 then begin
          nBuf:=InfoDoc.sizeEndBuf; SetLength(Buf,nBuf);
          Strm.ReadBuffer(Buf[0],SizeOf(Buf)*nBuf);
          for i:=0 to nBuf-1 do write(ff,chr(((Buf[i]-1000) div 3)-223));
        end
        else begin
          nBuf:=500;
          for i:=1 to InfoDoc.colBuf-1 do begin
            SetLength(Buf,nBuf);
            Strm.ReadBuffer(Buf[0],SizeOf(Buf)*nBuf);
            for j:=0 to nBuf-1 do write(ff,chr(((Buf[j]-1000) div 3)-223));
            SetLength(Buf,0);
          end;
          nBuf:=InfoDoc.sizeEndBuf; SetLength(Buf,nBuf);
          Strm.ReadBuffer(Buf[0], SizeOf(Buf)*nBuf);
          for i:=0 to nBuf-1 do write(ff,chr(((Buf[i]-1000) div 3)-223));
        end;
      finally
        SetLength(Buf,0);
        CloseFile(ff);
      end;
    end;
  finally
      // закрываем поток
    Strm.Free;
  end;
Проблема в том, что один и тот же закодированный файл то нормально декодируется, то вылезает какая-то шибка 'access violation ...'. Причем ошибка вываливается на операторе SetLength(Buf), но иногда и на ReadBuffer. Не могу понять в чем дело.
Elenik вне форума Ответить с цитированием
Старый 05.07.2017, 10:36   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Код:
Strm.ReadBuffer(Buf[0],SizeOf(Buf)*nBuf);
Stream.ReadBuffer требует АДРЕС(указатель) места (КУДА копировать данные).
если повезет значением байта(или слова как уж там объявлен buf) Buf[0] будет НЕ легитимный адрес и все, здравствуй AV.
А уж НЕ повезет и адрес окажется вполне легитимным, то при этом будет ИСКАЖЕНА какая-то совершено другая память, как правило это будет место хранения ДРУГИХ объектов, и тогда AV будет не сразу а при работе с этими "другими" переменными.

Цитата:
Проблема в том, что один и тот же закодированный файл то нормально декодируется
И вы сумели раскодировать файл закодированный вашей функцией?
учитывая что в Stream будет записана совершенно непредсказуемая информация (тоже замечание что и к ReadBuffer)
Цитата:
Код:
            Strm.WriteBuffer(Buf[(i-1)*500], SizeOf(Buf)*500);
          Strm.WriteBuffer(Buf[(InfoDoc.colBuf-1)*500], SizeOf(Buf)*InfoDoc.sizeEndBuf);
http://www.programmersforum.ru/showthread.php?t=310349 там есть про Stream и динамические массивы.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 05.07.2017 в 10:51.
evg_m вне форума Ответить с цитированием
Старый 05.07.2017, 14:09   #3
Elenik
Пользователь
 
Регистрация: 22.03.2013
Сообщений: 23
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение


И вы сумели раскодировать файл закодированный вашей функцией?
Вы не поверите, но вчера мне удалось несколько раз это сделать, причем текст в раскодированных документах полностью совпадал, но программа ругалась при закрытии, видимо это был случай, когда "НЕ повезло".

Попробовала использовать обычные массивы (не динамические) и команды
Strm.Read(Buf,SizeOf(Buf)) и Strm.Write(Buf,SizeOf(Buf)) и все получилось - вроде не ругается.

Спасибо! Тема закрыта
Elenik вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с чтением файла (TFileStream) Xo66um Общие вопросы Delphi 12 26.07.2015 09:52
C++ - непонятная проблема Namolem Помощь студентам 7 16.09.2011 00:56
Непонятная проблема CrazyDude Работа с сетью в Delphi 2 02.04.2010 00:35
Проблема с record,string,TFileStream AngelOfDeath Общие вопросы Delphi 6 31.05.2008 11:24