Obróbka pliku w PHP

Odpowiedz Nowy wątek
2010-10-01 23:59
0

Witajcie,
Jest plik. W pliku bloki po 56 bajtów.
1) Teraz trzeba odczytać plik blokowo do PackedRecord (tak to się w Delphi nazywa, a w php będzie to chyba tylko tablica 56 elementowych tablic).
2) Następnie (również w PHP) złożyć 8 pierwszych bajtów do postaci umożliwiającej odczytanie z niej wartości DateTime, a resztę po 4 bajty do postaci zmiennych typu Single i/lub LongWord.

Jak w PHP najprościej i jak najmniej obciążając serwer, odczytać plik blokowo?

Czy takie złożenie jest poprawne, czy może czegoś brakuje (?):

$DAT_path = "C:\history.dat";
$DAT_plik = fopen($DAT_path,'r');

//Na próbę odczyt pierwszych 56 bajtów...
$paczka = fread ($DAT_plik,56);

//Chyba nie dobrze / nie potrzebne ord() ...
$sk[0] = ord($paczka[8]);
$sk[1] = ord($paczka[9]);
$sk[2] = ord($paczka[10]);
$sk[3] = ord($paczka[11]);

$l = $sk[0] + ($sk[1] << 8) + ($sk[2] << 16) + ($sk[3] << 24);

Pozdro!
Michał

Pozostało 580 znaków

2010-10-02 00:08
0

Paczka to string, odwołujesz się do niego jak do tablicy. Jeśli chcesz skonwertować na tablicę, to użyj str_split.
Z typów zmiennych są: integer, float, string, bool, tablice, zasoby, funkcje i klasy więc z typowaniem masz ułatwioną sprawę.
Dodatkowo: W PHP plus to znak dodawania. Zawsze. Jeśli chcesz połączyć typy konwertowalne używaj kropek. Przykład:

$a = 1;
$b = 2;
$c = 'aaa';

$result = $a + $b; //3
$result = $a + $b + $c; //4 (string dłuższy niż 0 znaków konwertuje się do (integer)1 jak pamiętam)
$result = $a . $b; //12
$result = $c . $a . $b; //aaa12

Women were the reason I became a monk - and, ah, the reason I switched back...

Pozostało 580 znaków

2010-10-02 01:24
0
$string = file_get_contents($DAT_path);
$paczka = str_split($string,56);

$bajt[0] = ord($paczka[0][8]);
$bajt[1] = ord($paczka[0][9]);
$bajt[2] = ord($paczka[0][10]);
$bajt[3] = ord($paczka[0][11]);

Tak lepiej?

Teraz - jak z 4 bajtów złożyć liczbę zmiennoprzecinkową?

Pozostało 580 znaków

2010-10-02 01:53
0

Nie.

$DAT_path = "C:\history.dat";
$DAT_plik = fopen($DAT_path,'r');

//Na próbę odczyt pierwszych 56 bajtów...
$paczka = fread($DAT_plik,56);
$paczka = str_split($paczka);

$sk[0] = $paczka[8];
$sk[1] = $paczka[9];
$sk[2] = $paczka[10];
$sk[3] = $paczka[11];

$sklejamy = $sk[0] . $sk[1] . $sk[2] . $sk[3];
$sklejamy = $sklejamy / 1000;

fread jest wporzo, bo można potem odczytać kolejne 56 bajtów bez problemu. Za pomocą kropek się skleja, tutaj akurat nie uwzględniłem przecinka i potem podzieliłem przez tysiąc, w każdym razie możesz zrobić tak:

$sklejamy = $sk[0] . $sk[1] . ',' . $sk[2] . $sk[3];
$sklejamy = (float)$sklejamy;

Women were the reason I became a monk - and, ah, the reason I switched back...

Pozostało 580 znaków

2010-10-02 11:14
nav
0
unpack

utf-8 rlz! ٩(ಥ_ಥ)۶

Pozostało 580 znaków

2010-10-03 18:44
0

Lekko mnie przymuliło, ale już mam !
Dzięki [browar]

$paczka = fread($DAT_plik,56);

$sk[0] = ($paczka[40]);
$sk[1] = ($paczka[41]);
$sk[2] = ($paczka[42]);
$sk[3] = ($paczka[43]);

$l = $sk[0].$sk[1].$sk[2].$sk[3];

$b = unpack(f,$l);
$b = round($b[1],1);

Miało być 16.9 i jest :)

Pozostało 580 znaków

2010-10-03 19:22
nav
0

$b = unpack('f', substr($paczka, 40, 4));
Zamiast jakichś cudacznych kombinacji.
Albo nawet lepiej, fseek + fread tylko tego co potrzeba. Do unpack'a można podać więcej niż 1 znak w formacie - może Ci ładnie rozpakować cały rekord do tablicy, wysatrczy podać kolejne typy do rozpakowania.


utf-8 rlz! ٩(ಥ_ಥ)۶

Pozostało 580 znaków

2010-10-03 19:26
0

Kombinacje zostały w wyniku powolnego dochodzenia do prawdy. I tak zamierzałem to uprościć i ubrać w funkcję bo tych danych będzie z czasem parę MB do przerzucenia :>.

Pewnie tak to się robi...?

    $blok_format = 
            'f4/'. # Get the first 4 bytes
            'f4';  # Get the next 4 bytes

$sese = unpack($blok_format, substr($paczka, 36, 8) );

Powinno wyrzucić dwie liczby typu float, a nie działa... pewnie znów coś źle robię

Pozostało 580 znaków

2010-10-03 21:23
nav
0

"f4/f4" oznacza:

  • 4 floaty
  • / --- prawdopodobnie warning?
  • 4 floaty

Daje to w sumie 4xfloat_size bajtów, które mają się raczej nijak do 8 bajtów które podajesz funkcji.

Polecam czytanie ostrzerzeń, błędów itd a nie wyciszanie ich przez @, error_reporting czy display_errors.


utf-8 rlz! ٩(ಥ_ಥ)۶

Pozostało 580 znaków

2010-10-03 21:32
0

No tak... komentarz na pewnej stronce mnie zmylił - myślałem że:
f4 / f4 = float (4 bajty) / float (4 bajty), a nie to co piszesz.

Ehh...

$blok = unpack ('f1Pierwsza/'.'f1Druga', substr($paczka,36,8));

echo '<br>', Round($blok['Pierwsza'],1);
echo '<br>', Round($blok['Druga'],1);

Zostało jeszcze przeformatowanie daty i czasu...

$paczka = fread($DAT_plik,56);

$ukryta_data = substr($paczka, 1, 8);
echo '<br>'.$ukryta_data;
echo '<br>';

$dataczas = unpack('l1Data/l1Czas',$ukryta_data);
echo '<br>'.(date('d.m.y',$dataczas['Data']));
echo '<br>'.(date('H:i:s',$dataczas['Czas']));

Pozostało 580 znaków

2010-10-04 22:09
nav
0

Czytaj błedy PHP. W powyższym kodzie masz niezdefiniowane stałe, nieznane indeksy. Jak nic się nie pojawia, to polecam error_reporting(E_ALL) na początek skryptu + ewnetualnie ini_set('display_errors', 'on')


utf-8 rlz! ٩(ಥ_ಥ)۶

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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