odczyt z pliku [binaria]

0

Witam.
Mam problem z odczytaniem i konwersją danych z pliku w którym znajdują się
binaria. Plik składa się z 14 bajtowych segmentów. Segment natomiast dzieli się w
następujący sposób :

1-wszy Bajt : Numer porządkowy (Hexadecymalnie dla pierwszego elementu 01 dla drugiego 02 itd.).
2-gi Bajt : (nie bardzo wiem do czego służy ale w heksach jest to 00 (zawsze) możliwe, że oddziela nr porządkowy od danych(ale po co?)).
3-6 Bajt : 4 Bajty określające liczbę całkowitą longint unsigned.
7-10 Bajt : 4 Bajty określające liczbę zmiennoprzecinkową (single).
11-14 Bajt : 4 Bajty określające liczbę zmiennoprzecinkową (single).

(Otwierając plik w np. notatniku objawia mi się sama "chinszczyzna".)
Po otwarciu hexedytorem plik (właściwie jego część) wygląda następująco :

01 00 32640000 355E8741 BCF3BB3F
02 00 546F0000 EE7C8641 1F04BC3F
03 00 ..... itd. itp.

(odstępy wstawione w celu ort!; normalnie jest to jeden ciąg)

Chciałbym odczytać te informacje jako liczby dzisiętne i umieścić je w kolumnach
lub zapisać je do innego pliku używając Delphi. Siedzę już nad tym długo i nie
potrafię sobie z tym poradzić. Przjżałem FAQ-i, Tutoriale, Kursy, Google :d . Proszę o pomoc.

0
type
  TRekord: record
    Numer: Byte;
    a: Byte;
    b: LongWord; //unsigned 32 bity
    c: Single;
    d: Single;
  end;

  Tf: File of TRekord;

var
  f: Tf;
  r: TRekord;

begin
  AssignFile(f, 'c:\plik');
  Reset(f);
  While not EoF(f) do
  begin
    Read(f, r);
    // zrób coś z r
  end;
  CloseFile(f);
0

Dziękuje za szybką odpowiedź Misiekd [browar] . Ładnie to wygląda lecz pętla przestaje działać w tym momencie :
01 00 32640000 355E8741 BCF3BB3F
02 00

i dalej nie pobiera danych.

powyższy odczyt z pliku test.txt (oczywiście odczytane za pomocą hexedytora).
Tak to wygląda u mnie.

type
  TRekord = record
    Numer : Byte;
    shit : Byte;
    czas : LongWord;
    temp : Single;
    wolt : Single;
  end;
  Tf1 = File of TRekord;
  Tf2 = File of TRekord;

procedure TForm1.Open_Button1Click(Sender: TObject);

var
  plikDo : Tf1;
  plikZ  : Tf2;
  r : TRekord;

begin
if Form1.OpenDialog1.Execute
        then
         begin
        AssignFile(plikDo, 'c:\test.sdd');
        AssignFile(plikZ, 'c:\test.txt');
        Reset(plikDo);
        Rewrite(PlikZ);
         While not EoF(plikDo) do
          begin
                Read(plikDo, r);
                Write(plikZ, r);
          end;
                CloseFile(plikDo);
                CloseFile(plikZ);
          end;
end;

Przejrzałem to kilka razy i nie widzę błędu ale nie wiem dlaczego pętla wykonuje się poprawnie tylko raz, a za drugim razem przestaje działać?

0

zazwyczaj odczytuje się z pliku źródłowego a zapisuje do docelowego a nie na odwrót :P (biorąc pod uwagę nazwy zmiennych)

Read(plikDo, r);
Write(plikZ, r);

czy aby na pewno z dobrego pliku czytasz?

0

jak dobrze pamietam to funkcja read przyporządkowuje całą zawartość pliku (albo do końca lini, ale nie pamietam dokładnie) do podanej struktury, spróbuj zamienić read na blockread i powinno działać

0
nul napisał(a)

jak dobrze pamietam to funkcja read przyporządkowuje całą zawartość pliku (albo do końca lini, ale nie pamietam dokładnie) do podanej struktury, spróbuj zamienić read na blockread i powinno działać

no niestety źle pamiętasz. Może przedtem wypadało by sobie przypomnieć co do czego jest

http://www.delphibasics.co.uk/RTL.asp?Name=Read
http://www.delphibasics.co.uk/RTL.asp?Name=BlockRead

ts81 jeśli to nie jakiś tajny plik to zamieść tutaj plik, który ma chociaż 3 przykładowe bloki danych, albo lepiej ten, którego wczytać nie możesz

0
ts81 napisał(a)

1-wszy Bajt : Numer porządkowy (Hexadecymalnie dla pierwszego elementu 01 dla drugiego 02 itd.).
2-gi Bajt : (nie bardzo wiem do czego służy ale w heksach jest to 00 (zawsze) możliwe, że oddziela nr porządkowy od danych(ale po co?)).

Moim zdaniem to jest to starszy bajt numeru porzadkowego.

0

Misiekd napisał :

zazwyczaj odczytuje się z pliku źródłowego a zapisuje do docelowego a nie na odwrót (biorąc pod uwagę nazwy zmiennych)

PlikDo to plik do odczytu a PlikZ plik do Zapisu (trochę pokrętnie może) :)

spc napisał :

Moim zdaniem to jest to starszy bajt numeru porzadkowego.

Być może, ale jestem pewien że 01 00 czy też samo 01 ma oznaczać akurat pierwszy zbiór jedynkę a 02 00 / 02 drugi zbiór.

Nie są to tajne pliki niestety nie wiem jak je umieścić na forum mogę podesłać e-maila.
Pozdrawiam.

0

misiekd(at)poczta(dot)fm

albo daj ten plik na jakiś FTP albo na np. rapidshare.de

nie chce mi się sprawdzać, ale coś mi się wydaje, że dane tam są zapisywane inaczej, tzn może się nie zgadzać kolejność bajtów dla LongWord i Single. Jeśli odczytasz z pliku dane jako Byte to wsio jest OK

procedure TForm1.btn1Click(Sender: TObject);
type
  TRekord = array [1..14] of Byte;
  Tf = File of TRekord;

var
  f: Tf;
  r: TRekord;
  ARow: Integer;
  ACol: Integer;

begin
  AssignFile(f, 'c:\test\T1SEG9.SDD');
  Reset(f);
  While not EoF(f) do
  begin
    Read(f, r);
    ARow := sg1.RowCount - 1;
    sg1.RowCount := sg1.RowCount + 1;
    for ACol := 0 to 13 do
      sg1.Cells[ACol, ARow] := IntToStr(r[ACol + 1]);
  end;
  CloseFile(f);
end;

sg1 to StringGrid

0

Misiekd napisał :

nie chce mi się sprawdzać, ale coś mi się wydaje, że dane tam są zapisywane inaczej

Dane są zapisane dokładnie tak jak już napisałem. Problem leży po stronie odczytu. Gdy pobieram z pliku dane korzystając z rekordu napisanego przez Misiekd pobierane są [BYTE|BYTE|następnie dwa baty są pomijane|LONGWORD|SINGLE|SINGLE]. Dlaczego pomiajne są te dwa bajty ??
Wygląda na to że wyrównuje do 4 bajtów. Gdy dopisałem do pliku z danymi dwa bajty na początego każdego segmentu to jest wszystko ok [???] . Jakieś sugestie ??
Pozdrawiam

0
ts81 napisał(a)

Wygląda na to że wyrównuje do 4 bajtów. Gdy dopisałem do pliku z danymi dwa bajty na początego każdego segmentu to jest wszystko ok [???] . Jakieś sugestie ??
Pozdrawiam

Jesteś genialny :). No widzisz tak to jest jak się z czegoś nie kożysta długo. Przecież zwykły rekord wyrównywany jest do 4 bajtów!

zamiast

  TRekord = record
    Numer: Byte;
    a: Byte;
    b: LongWord; //unsigned 32 bity
    c: Single;
    d: Single;
  end;

daj

  TRekord = packed record
    Numer: Byte;
    a: Byte;
    b: LongWord; //unsigned 32 bity
    c: Single;
    d: Single;
  end;
0

Dziękuje Ci Misiekd za wszystko. Teraz ładnie śmiga i wczytuje pliczki aż miło.
Pozdrawiam.

0
ts81 napisał(a)

Dziękuje Ci Misiekd za wszystko. Teraz ładnie śmiga i wczytuje pliczki aż miło.
Pozdrawiam.

Mi nie dziękuj - sam na to wpadłeś tylko o tym nie wiedziałeś :)

0

Ok. Czyli teraz odczytuje wartości rekordowo (stała długość poszczególnych rekordów/stała długość pliku) z pliku zdefiniowanego. A jeśli w pliku będą zawarte oprócz tych danych inne dane czyli plik stanie się plikiem niezdefiniowanym to nie możemy użyć:

File of nazwa_rekordu_typu

tylko: File

 Wtedy nie można używać własnych zdefiniowanych rekordów. Jak odczytać taki niezdefiniowany plik ? Niewiele informacji w tutorialach ani też faq-ach na ten temat.
0

do plików niezdefiniowanych jest BlockRead

0

Nie wiem czy tu z tym mogę ale ehh....
A więc odczytuję zbiór danych z pliku i chcę z utworzyć wykres tych danych lecz coś zgrzyta i nie wiem co oto kod :

procedure TForm1.Open_Button1Click(Sender: TObject);

type
   TRekord = packed record
    Numer : smallint;
    czas : LongWord;
    temperatura : Single;
    wolt : Single;
  end;

  Tf1 = File of TRekord;

var
  plikDoOdczytu : Tf1;

  r : TRekord;
  nr, time, temperature, voltage : string;
  nazwa_zbioru : string;
  x, y : single;

begin

if Form1.OpenDialog1.Execute
        then
         begin

         nazwa_zbioru := OpenDialog1.FileName;
         AssignFile(PlikDoOdczytu, nazwa_zbioru);
         Reset(PlikDoOdczytu);

          While not EoF(PlikDoOdczytu)
           do
            begin
                Read(PlikDoOdczytu, r);

                x := r.temperatura;
                y := r.wolt;

                Series1.addXY(x, y);

                end;

                CloseFile(PlikDoOdczytu);

         end;
end;

Kompiluje się bezbłędnie. Natomiast po wczytaniu danych z pliku pojawia się błąd:
Project Project1.exe raised exception class EListError with message 'List index out of bounds(1)'. Process stopped.
Jeśli zakomentuję linię

Series1.addXY(x, y);

bądź x := r.temperatura;
y := r.wolt;

To program odpala się bez zarzutów. Ktokolwiek... Misiekd liczę na Ciebie  ;) .

Poprawiłem.  Przepraszam mój błąd. 

Series1 to jest pierwsza seria wykresu (TChart).
Dla jasności jak wpiszę (przykładowo) do tego kodu (powyżej) te dwie linie :
```delphi
 for i:= 1 to 10 do
              series1.addXY(i, random(10));

to wykres się pojawia złożony z i oraz random(10).

Wiem że topornie tłumacze ale jestem nowicjusz w Delphi.
Pozdrawiam.

0

co to jest Series1?

i jak dajesz kod to weź go w < delphi> < /delphi> a nie < quote> (możesz wyedytować tamten post)

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