odczyt z pliku [binaria]

odczyt z pliku [binaria]
T8
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 17 lat
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>przejżystości</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.

Misiekd
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
  • Postów:7923
0
Kopiuj
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);

- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
T8
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 17 lat
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.

Kopiuj
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ć?

Misiekd
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
  • Postów:7923
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)

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

czy aby na pewno z dobrego pliku czytasz?


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
NU
  • Rejestracja:prawie 22 lata
  • Ostatnio:ponad rok
  • Postów:196
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ć


Profesjonaliści są przewidywalni.
Strzeż się amatorów!!!!
Misiekd
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
  • Postów:7923
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


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
spc
  • Rejestracja:ponad 19 lat
  • Ostatnio:prawie 6 lat
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.


00, OK, 00, 00
...dziś się to robi na sprzętach, kiedyś na patentach...
T8
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 17 lat
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.

Misiekd
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
  • Postów:7923
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

Kopiuj
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


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
T8
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 17 lat
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

Misiekd
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
  • Postów:7923
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

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

daj

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

- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
T8
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 17 lat
0

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

Misiekd
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
  • Postów:7923
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ś :)


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
T8
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 17 lat
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ć:

Kopiuj
File of nazwa_rekordu_typu

tylko: File

Kopiuj
 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.
Misiekd
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
  • Postów:7923
0

do plików niezdefiniowanych jest BlockRead


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
T8
  • Rejestracja:prawie 19 lat
  • Ostatnio:około 17 lat
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 :

Kopiuj
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ę

Kopiuj
Series1.addXY(x, y);

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

Kopiuj
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.

Misiekd
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 12 lat
  • Postów:7923
0

co to jest Series1?

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


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)