Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Замена байтов в файле 
V
    Опции темы
Cashey
Дата 8.11.2006, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60



Подскажите, плиз. Такая ситуация: есть файл нетипизированной структуры, необходимо поменять значение предположим 10 байта независимо от того какое там было значение на определенную константу. можно с примером


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Romikgy
Дата 8.11.2006, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



а что сложного открываем файл ищем нужную позицию и пишем что нужно


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Snowy
Дата 8.11.2006, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



PM MAIL   Вверх
Cashey
Дата 8.11.2006, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60



Snowy, спасибо. не подскажешь, твой код добавляет байты в позицию, смещая остальные, или перезаписывает существующие?
и второе, непрокомментируешь эту строчку?
Код

fs.Seek($A200, soBeginning); // прописать в позицию в файле $A200

если я знаю порядковый номер байта в файле, то как мне его найти? что означает $A200?


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Alexeis
Дата 8.11.2006, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Cashey, перезаписывает. 
 $A200 - это и есть порядковый номер байта, но 16-тиричном виде.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Cashey
Дата 10.11.2006, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60



Snowy, что то не работает. Пишу:
Код

procedure replacebyte(cFileName:String) ;
var
  fs: TFileStream;
  s:  string;
begin
  s := #$FF#$AB#$28#$4A; // Íàïðèìåð õîòèì ïðîïèñàòü òóäà áàéòû FF AB 28 4A
  try
    fs := TFileStream.Create(cFileName, fmOpenReadWrite or fmShareDenyNone);
    try
      fs.Seek(1, soBeginning); // ïðîïèñàòü â ïîçèöèþ â ôàéëå $A200
    //$A200
        fs.Write(s[1], Length(s));
    finally
      fs.Free;
    end;
  except
     showmessage('error');
  end;
end;

По идеи вроде бы должно перезаписатся 4 байта начиная с первого, но этого не происходит. т.е. когда просматриваю файл через HEX редактор ничего не меняется

Это сообщение отредактировал(а) Cashey - 10.11.2006, 11:49


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Matematik
Дата 10.11.2006, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1027
Регистрация: 11.3.2006

Репутация: 17
Всего: 50



Цитата(Cashey @ 10.11.2006,  11:48)
Snowy, что то не работает. Пишу:
Код

procedure replacebyte(cFileName:String) ;
var
  fs: TFileStream;
  s:  string;
begin
  s := #$FF#$AB#$28#$4A; // Íàïðèìåð õîòèì ïðîïèñàòü òóäà áàéòû FF AB 28 4A
  try
    fs := TFileStream.Create(cFileName, fmOpenReadWrite or fmShareDenyNone);
    try
      fs.Seek(1, soBeginning); // ïðîïèñàòü â ïîçèöèþ â ôàéëå $A200
    //$A200
        fs.Write(s[1], Length(s));
    finally
      fs.Free;
    end;
  except
     showmessage('error');
  end;
end;

По идеи вроде бы должно перезаписатся 4 байта начиная с первого, но этого не происходит. т.е. когда просматриваю файл через HEX редактор ничего не меняется

Работает.
Перезаписывает начиная со 2го байта

Это сообщение отредактировал(а) Matematik - 10.11.2006, 11:55
PM MAIL WWW ICQ   Вверх
Cashey
Дата 10.11.2006, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60



ладно, поковыряюсь еще


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Cashey
Дата 19.5.2009, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60



в продолжение темы....
как найти в TFileStream заданную последовательность байтов, для определения номера вхождения для функции Seek()?
проще говоря надо найти и заменить заданную последовательность байтов.


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Christoph
Дата 19.5.2009, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: 1
Всего: 11



считывай в буфер, затем StringReplace (в справке описание функции), и заново записывай строку в файл 


--------------------
user posted image
PM MAIL ICQ   Вверх
Alexeis
Дата 19.5.2009, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(Cashey @  19.5.2009,  11:37 Найти цитируемый пост)
проще говоря надо найти и заменить заданную последовательность байтов. 

Длины последовательностей совпадают или нет? 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Cashey
Дата 19.5.2009, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60



Цитата(Alexeis @  19.5.2009,  14:33 Найти цитируемый пост)
Длины последовательностей совпадают или нет?

нет, не совпадают. но нужно найти первую позицию входа

пытаюсь пройти весь файл по блокам для сравнения с заданой последовательностью:
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  fs: TFileStream;
  s1 :  string;  //значение, которое надо вставить
  s :  string;   // последовательность, которую надо найти
  s2:  string;   // буфер для чтения из файла
  i: cardinal;
begin
  s :=#$55#$50#$44#$41#$54#$45#$20#$61#$72#$74#$69#$6B#$75#$6C#$20#$53#$45#$54#$20#$6E#$61#$6D#$65#$20#$3D#$20#$27#$27#$0D#$0A ;
  s1 := #$50#$52#$4F#$43#$45#$44#$55#$52#$45#$20#$4C#$6F#$61#$64#$0D#$0A ;
  try
  if OpenDialog1.Execute then
  fs := TFileStream.Create(OpenDialog1.FileName, fmOpenReadWrite or fmShareDenyNone) else exit;
    try
  fs.Seek(0, soBeginning);
    for i := 0 to round(fs.Size/Length(s1))  do begin
     ProgressBar1.Position := ProgressBar1.Position+1;
     application.ProcessMessages;

    fs.Seek(Length(s1)+ fs.Position, soBeginning);
    SetLength(s2, Length(s1));
    fs.Read(s2,Length(s2))  ;
    if s2=s1 then
 //   fs.Write(s[1], Length(s))
      showmessage(s2) ;
    end;
    finally
      fs.Free;
    end;
  except end;
end;


но почему то после fs.Read(s2,Length(s2))  ; s2 всегда пустое. как правильно считать данные из потока?


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Alexeis
Дата 19.5.2009, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



  Файл больше 50кб? Или меньше?

Если файл большой, то нужно будет производить поблочное чтение и замену внутри блока с последующей записью в новый файл. Если каждый раз удлинять блок размером мегабайт в 10 и копировать огромный остаток, то операция займет кучу времени. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Cashey
Дата 19.5.2009, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бессмертный
****


Профиль
Группа: Завсегдатай
Сообщений: 3441
Регистрация: 13.11.2002
Где: в столице

Репутация: 2
Всего: 60



размер файла примерно 160 кб


--------------------
библия учит любить ближнего, а камасутра обучает как именно
PM Jabber   Вверх
Alexeis
Дата 19.5.2009, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Вот написал быстрый алгоритм поиска с заменой без частых алокаций памяти (размер файла не выше 1Мб иначе большие расходы памяти)
Код

uses strUtils;

procedure TForm1.FormCreate(Sender: TObject);
var
  F   : TFileStream;
  str : AnsiString;
  pstr, newstr : PAnsiChar;
  s1, s2 : AnsiString;
  i, lastpos, cnt : Integer;
  poss : array of integer;
  newlen : Integer;
  p1, p2, pp : Integer;

begin
 // s1 := #$54#$45;  //ищем
 // s2 := #$54#$45#$00#$00#$00#$00#$00#$00; //заменяем
  s1 := '67';  //ищем
  s2 := '6700'; //заменяем
//  s1 := '6789';  //ищем
//  s2 := '67'; //заменяем
  //читаем все данные в память
  try
    F := TFileStream.Create('1.dat', fmOpenRead);
    try
      SetLength(str, F.Size);
      SetLength(poss, F.Size);
      F.Read(str[1], F.Size);
    finally
      F.Free;
    end;
  except end;
  //сохраняем все найдейнные позиции
  lastpos := 1; cnt := 0;
  repeat
    i := PosEx(s1, str, lastpos);
    if (i <> 0)
    then
      Begin
        poss[cnt] := i;
        lastpos   := i + 1;
        inc(cnt);
      end;
  until i = 0;
  //вычисляем новый размер
  newlen := Length(str) + (Length(s2) - Length(s1)) * cnt;//новый размер
  newstr := stralloc(newlen);
  pstr   := PAnsiChar(str);
  //заменяем участки в памяти
  p1 := 0; p2 := 0; pp := 1;
  for i := 0 to cnt - 1 do
  begin
    Move(pstr[p1], newstr[p2], poss[i] - pp);
    p2 := p2 + poss[i] - pp;
    pp := poss[i] + Length(s1);
    Move(PAnsiChar(s2)[0], newstr[p2], Length(s2));
    inc(p2, Length(s2));
    p1 := poss[i] + Length(s1) - 1;
  end;
  Move(pstr[p1], newstr[p2], Length(str) - pp + 1);
  //сохраняем на диск
  try
    F := TFileStream.Create('2.dat', fmCreate or fmOpenWrite);
    try
      F.write(newstr[0], newlen);
    finally
      F.Free;
    end;
  except end;

  StrDispose(newstr);
end;




--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0690 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.