[delfin] edycja pliku binarnego

0

Mam plik binarny ok. 200kB
Chce otworzyc plik, znalezc okreslony tekst, zmienic go, zamknac plik i zapisac zmiany.
Jak to zrobic?

0

darek963 napisał:

&gtMam plik binarny ok. 200kB
&gtChce otworzyc plik, znalezc okreslony tekst, zmienic go, zamknac plik i zapisac zmiany.
&gtJak to zrobic?
&gt

Zrob bufor (najlepiej string)
Otworz plik przez Reset jako nietypowany lub file of byte;

Ustaw dlugosc bufora na dlugosc pliku (SetLength)

Wczytaj plik do bufora przez BlockRead(F, Bufor[1], FileSize[F]);

Ustal, gdzie jest tekst (funkcja Pos)

Przejdz na odpowiednie miejsce w pliku (Uwaga, pliki sa indeksowane od zera) (funkcja Seek)

Zapisz swoj tekst przez BlockWrite(F, MojTekst[1], Length(MojTekst));

zamknij plik

Mozesz tez podmienic tekst w buforze i zapisac caly bufor, ale to niezbyt eleganckie: wymaga zapisu 200kB kiedy potrzebujesz podmienic jedynie krotki(zapewne) tekst.

Uwaga: lancuchy oryginalny i podmieniany musza byc tej samej dlugosci. Jesli Twoj jest krotszy, to dopelnij go spacjami. Jesli jest dluzszy to skroc. Teoretycznie moglbys wpisac dluzszy lancuch usuwajac oryginal z bufora funkcja Delete i wpisujac swoj tekst przez Insert. Jednak plik jest binarny wiec zapewne zawiera jakies wewnetrzne wskazniki, ktore sie skopia przy zmianie dlugosci.

--
Pawel {Delphi 6 Personal}

Po pierwsze: naciśnij F1

0

pq napisał:
Wczytaj plik do bufora przez BlockRead(F, Bufor[1], FileSize[F]);
I w tym momencie też bym stosował BlockRead :D

Uwaga: lancuchy oryginalny i podmieniany musza byc tej samej dlugosci. Jesli Twoj jest krotszy, to dopelnij go spacjami. Jesli jest dluzszy to skroc. Teoretycznie moglbys wpisac dluzszy lancuch usuwajac oryginal z bufora funkcja Delete i wpisujac swoj tekst przez Insert. Jednak plik jest binarny wiec zapewne zawiera jakies wewnetrzne wskazniki, ktore sie skopia przy zmianie dlugosci.
A jak by chciał zapisać dłuższy lub krótszy, to musi przekopiować wszystko co znajduje się za zmienianym tekstem i wstawić trochę dalej lub bliżej... choć jak znam życie to na pewno istnieje efektywniejszy algorytm.--Jest jeszcze jeden błąd ... :)

Apel: Piszcie w tematach o jaki język programowania chodzi np. : [Delphi], [C++], itp.

Pomoc do Delphi po polsku. http://www.4programmers.net/forum/index.php?action=show&id=21335&c=2

Oficjalny kanał IRC serwisu 4programers:
serwer: warszawa.ircnet.pl sieć: POLNet kanał: #4programmers.net

0

Dryobates napisał:

&gtA jak by chciał zapisać dłuższy lub krótszy, to musi przekopiować wszystko co znajduje się za zmienianym tekstem i wstawić trochę dalej lub bliżej... choć jak znam życie to na pewno istnieje efektywniejszy algorytm.
&gt

Chodzilo mi o to, ze plik binarny ma zapewne jakas strukture (pola) i niektore pola moga zawierac wskazniki (adresy wzgledem poczatku pliku) innych pol. Kiedy zmieniasz dlugosc wstawianego stringu (mozna to zrobic na buforze przez Delete i Insert a potem Seek(F, 0) i BlockWrite zmienionego bufora) wtedy pola wskazywane znajdujace sie za zmienionym stringiem sie przesuwaja. Nalezaloby updatowac pola wskazujace, ale bez znajomosci struktury pliku jest to niemozliwe. Bez updatowania struktura sie rozsypie i oryginalny program nie odczyta pliku.--Pawel {Delphi 6 Personal}

Po pierwsze: naciśnij F1

0

pq napisał:
Chodzilo mi o to, ze plik binarny ma zapewne jakas strukture (pola) i niektore pola moga zawierac wskazniki (adresy wzgledem poczatku pliku) innych pol.

Ja zwykle pliki robię bez wskaźników (choć zdarza się i tak) dla zminimalizowania wpływu modyfikacji. Ale uwaga jest absolutnie słuszna (ja już bym zepsuł plik :D )--Jest jeszcze jeden błąd ... :)

Apel: Piszcie w tematach o jaki język programowania chodzi np. : [Delphi], [C++], itp.

Pomoc do Delphi po polsku. http://www.4programmers.net/forum/index.php?action=show&id=21335&c=2

Oficjalny kanał IRC serwisu 4programers:
serwer: warszawa.ircnet.pl sieć: POLNet kanał: #4programmers.net

0

Poradzilem sobie w taki sposob:

procedure TForm1.Zamiana;
var
Plik:file of char;
bufor:array[1..200000] of char;
i,dl:integer;

begin
assignfile(plik,'key.ke2');
reset(plik);

i:=0;
while not eof(plik) do
begin
inc(i);
read(plik,bufor[i]);
end;
dl:=i;
closefile(plik);

i:=0;
repeat
inc(i);
begin
if bufor[i]='a' then bufor[i]:='b
end;
until i&lt&gtdl;

rewrite(plik);
for i:=1 to dl do
begin
write(plik,bufor[i]);
end;
closefile(plik);

showmessage('koniec');
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1