Jak zapisać pusty bajt za pomocą string?

0

Witam, piszę gdyż nie mogę sobie poradzić z (pozornie błahym) problemem.
Chcę przeprowadzić prostą operację na pliku tekstowym: wczytać go do pamięci, odnaleźć konkretną wartość, zmodyfikować i zapisać. I tu zaczynają się schody, bo okazało się że plik jest dosyć specyficzny.

Żeby zobrazować:
Stwórzcie u siebie plik tekstowy (txt). Otwórzcie go, wklejcie do środka te 2 znaki: '˙ţ' (oczywiście bez cudzysłowy), zapiszcie i zamknijcie. Otwórzcie ponownie i co się okazuje? Plik jest pusty... Nie do końca jednak, jego rozmiar to 2 bajty (czyli te znaki nadal tam są, choć niewidoczne dla systemowego notatnika). Ponadto plik zyskał "ciekawą" właściwość. Wpiszcie do niego dajmy na to wyraz PRZYKŁAD i zapiszcie. Otwórzcie - Nic się nie zmieniło. Jednak jest pewna różnica, rozmiar pliku to 18 bajtów - dziwne bo normalnie powinien zajmować 8! Sprawa wyjaśnia się gdy otworzymy go dowolnym edytorem hex. Okazuje się że przy takim "kodowaniu", między każdy wprowadzony przez nas bajt (czyli literkę), automatycznie wciskany jest pusty bajt (czyli w hexach 00), więc w rzeczywistości wygląda to tak: P R Z Y K Ł A D (+ oczywiście 2 znaki na początku, które są niewidoczne), czego jednak nie widać, gdyż edytory tekstu opuszczają puste bajty.

Teraz do rzeczy (opis problemu):
Jak pisałem chcę ten plik zmodyfikować, ale nie mogę sobie z tym poradzić. Próba wczytania do Memo, RichEdit czy ListBox kończy się niepowodzeniem. Wprawdzie pojawia się kilka znaków (nawet te początkowe '˙ţ' które dla normalnego edytora są niewidoczne). Jednak gdy program natrafia na pierwszy, pusty bajt, przerywa (więc tak na prawdę odczytuje tylko pierwsze 3 bajty!).

Podjęte próby:
Wymyśliłem że otworzę sobie plik jako FileStream, a potem odczytam go w hexach i wtedy zmodyfikuję wedle uznania. Wszystko poszło gładko, tylko że nie wiem jak mam teraz odwrócić proces. Nie mogę po prostu przekonwertować hexów na stringi, gdyż pusty bajt nie ma swojego odpowiednika jako znak garficzny! Taka zamiana może zostać przeprowadzona, ale wtedy puste bajty zostaną opuszczone (widać po sprawdzeniu edytorem hex i znacznie zmniejszonym rozmiarze pliku) - czyli odpada...

Pomysł:
Jest dziwny i "chałupniczy", ale może zadziałać. Mógłbym stworzyć nowy plik i zakodować go (dodając te 2 znaki). Potem otworzyć ten plik edytorem w stylu notatnika (tylko że z poziomu mojego programu), wkleić tekst pochodzący z zakodowanego pliku (lecz pozbawiony pustych bajtów - żebym mógł go normalnie obrabiać w edytorach z Delphi) i zapisać. Wtedy automatycznie zostaną wprowadzone puste bajty. Problem w tym że z edytorami z Delphi to nie działa, bo one nie odczytują tego '˙ţ' jak kodu, tylko jak zwykłe znaki. Jeżeli więc użyję np.

Memo1.Lines.SaveToFile(plik.txt)

Wtedy owszem zawartość zostanie tak zapisana, ale wcześniejszy kod (czy 2 pierwsze bajty) po prostu zniknie, bo zostanie przez Memo nadpisany... Próbowałem też łączyć, to znaczy wrzucałem do memo kod + resztę tekstu, ale ie działa - musi to zostać wykonane stopniowo. Najpierw kod, a gdy zostanie "wchłonięty" do pliku przy jego zapisie - wtedy reszta. No i warunek że musi to być edytor który respektuje te znaki jako kod, a nie zwykłe szlaczki (czy jakiś komponent z Delphi to potrafi?).

Prośba:
Proszę pomóżcie mi to jakoś rozwiązać, może macie inne pomysły jak mógłbym pracować na tym pliku, a później zapisać gotowe zmiany, bez naruszania jego struktury?

0

Na mój gust te 2 znaki: '˙ţ' na początku pliku to BOM, na podstawie którego edytory tekstu rozpoznają Unicode i następnie w czasie edycji/zapisu konsekwentnie się tego trzymają. Twój program też musi się do tego dostosować tak jak napisał _13th_Dragon.

0

A jak to osiągnąć w Delphi? Nie proszę o napisanie tego za mnie ale o jakieś podpowiedzi... Polski/Angielski wszystko jedno, byle było w miarę prosto objaśnione z czym to się je i jak to obsłużyć.

0

"pusty bajt" - rozumiem, że masz na myśli zero (znane też jako znak #0, który jak najbardziej da się zapisać w stringu - 'tekst'#0'dalszytekst').
nie otwieraj pliku binarnego w notatniku, to nie będziesz mieć takich problemów. jeśli już musisz podejrzeć zawartość, to użyj jakiegoś hex viewera/edytora (w total commandera masz taki wbudowany).

0

Czytaj ze zrozumieniem. Pusty bajt czyli w ASCII 0, w hexach 00. W String odpowiednika brak. Wrzuć sobie taki kodzik w Delphi to zobaczysz:

 Edit1.Text:=Chr(StrToInt('$00')); 

Edit będzie pusty, gdyż nie potrafi rozpoznać takiego znaku.

Poza tym napisałem wyraźnie że nie jest to plik binarny, a ZWYCZAJNY PLIK TEKSTOWY, tylko że z kodowaniem. Ma rozszerzenie txt, można go normalnie otworzyć i przeczytać notatnikiem, wygląda zupełnie zwyczajnie. Różnica jest taka że po każdym znaku jest pusty bajt, czego np. notatnik nie widzi (trzeba otworzyć edytorem hex by było to zauważalne).

Może zapytam inaczej - Jak napisać procedurę, która otworzy dowolny plik tekstowy, wplecie co każdy bajt (czyli jeden znak) pusty bajt i zapisze? Coś takiego też mnie urządza.

0

ustaw sobie s := #0; i podejrzyj sobie w debugerze stan zmiennej. to, że edit nie wyświetla, to sprawa czegoś zupełnie innego (lpsz).
w ASCII 0 to 48 :P

skoro to plik tekstowy, to wczytaj go jako utf-16 i z takim formatowaniem zapisz (uwzględniając BOM).

0

skoro to plik tekstowy, to wczytaj go jako utf-16 i z takim formatowaniem zapisz (uwzględniając BOM).

Tylko jak to zrobić? Poczytałem trochę teorii, wiem że chodzi o kodowanie i zapis bajtów, ale dalej nie mam pojęcia jak się za to zabrać z poziomu Delphi. Jakaś podpowedź, kawałek kodu?

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