Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] pobieranie danych z pliku
Forum PHP.pl > Forum > Przedszkole
lukash82
Witam,

Mam pewien plik na serwerze, który co minutę jest nadpisywany nowym wierszem danych ze stacji pogodowej. Muszę wybrać z tego pliku ostatni wiersz i przedstawić parę danych z wybranego ostatniego wiersza. Pytanie tylko, czy to co napisałem jest w miarę optymalne i nie będzie zbytnio zamulać strony... Plik txt waży od 300 do 550 kb, zależnie od pory dnia.

  1. $plik = file('plik.txt');
  2. $tmp1 = count($plik);
  3. $ostatnia = $plik[$tmp1-1];
  4. $spacje_out = explode(" ", $ostatnia);
  5. $tmp2 = count($spacje_out);


Jak widać, filozofii wielkiej tu nie ma. Ostatnie dwie linijki rozdzielają mi wybrany wiersz wg spacji, między którymi zapisywane są dane do pliku. Chodzi głównie o to, czy taka forma obróbki pliku o takiej objętości jest optymalna... Dzięki z góry za opinie, pozdr.
Sephirus
Podejście jest jak najbardziej ok. Pasowałoby jedynie zastanowić się nad FLOCKiem jeśli odpytania są strasznie częste. Jedyna wada jaką widzę to to że ładujesz cały plik do pamięci (500kb to tak średnio w sumie). Można by było otworzyć plik, znajać jego rozmiar i jakiś mniej-więcej rozmiar średni linijki pojedynczej przesunąć wskaźnik na KONIEC - DLUGOSC_LINII i pobrać tylko ostatnią linię (z jakimś nadmiarem). Explodujesz wtedy po "\n" i bierzesz ostatni element. To tylko poprawka na pamięć. wydajnościowo w sumie może też pomóc ale trzeba by to przetestować wink.gif
!*!
Ostatnią linię pliku można pobrać na kilka sposobów...

  1. $file_name = 'file.txt';
  2. $data = file($file_name);
  3. // 1
  4. $line = array_pop($data);
  5. echo $line;
  6.  
  7. // 2
  8. $line = $data[count($data)-1];
  9. echo $line;
  10.  
  11. // 3
  12. $file = escapeshellarg($file_name);
  13. $line = `tail -n 1 $file`;
  14. echo $line;


Sam musisz dokonać pomiarów który w Twoim wypadku będzie szybszy, choć dużych różnic bym się nie spodziewał. Btw. 550kb to sporo jak na odczyt pogody, to są zestawienia dla całego kraju?
lukash82
Ok, dzięki za opinie.

To są zestawienia dla jednej stacji pogodowej na stacji narciarskiej zapisywane co minutę tak jak pisałem wyżej. W każdej linijce jest zapisywanych 28 pomiarów (oprócz daty i godziny temp., temp. odczuwalna, opad, opad 1h, wilgotność, ciśnienie, wiatr i kierunek, porywy wiatru, etc.) Dane są trzymane w postaci obecny dzień i dzień wcześniejszy. Tego niestety nie mam możliwości zmienić. Muszę bazować na tym co jest.

Co do ilości zapytań to średnio jest to około 50 użytkowników jednocześnie na stronie, odwiedzin uu około 1,5k/dzień na chwilę obecną (nie wiem jak będzie w sezonie narciarskim).

Dużo czy mało? Bo jakoś nigdy nie zwracałem na to uwagi...
!*!
Właśnie sam zrobiłem "pomiar" dla pliku 600kb:
Kod
kod nr 1 - czas pobierania 0.359 sekundy.
kod nr 2 - czas pobierania 0.369 sekundy.
kod nr 3 - czas pobierania 0.022 sekundy.


Wrzuć pobraną linię w cache jak masz taką potrzebę, bo po co za każdym razem mielić te same dane.
lukash82
Dzięki za pomiar.

W sumie co minutę są nowe dane, choć pewnie nie różnią się między sobą jakoś drastycznie. Też tak myślałem, czy nie wybierać jednej linii pogody co np. 10min i zapisywać jej gdzieś do innego pliku. I potem wyrzucać dane z tego pliku osobnym zapytaniem przy okazji sprawdzając godzinę ostatniego wpisu. Jeśli się różni o więcej niż 10min to nadpisać go nowymi danymi. Jeśli nie to pokazać dane jakie są.

Co do bardziej fachowego cachowania to niebardzo mam czas na przetrawienie tego co znalazłem w sieci. Moje PHP jest raczej średnie... A strona musi ruszyć za parę godzin:/


Ew. ustawianie ciastka na 10min. Jeśli ciastko jest to nie pobiera nowych danych i już... Takie trochę łopatologiczne rozwiązanie...


Teraz też dowiedziałem się, że dostęp do shella mam zablokowany:/
Sephirus
hmmm no to kiepsko. A czy masz możliwość edycji kodu zapisywania tych danych? Jeśli byś miał to oprócz normalnego dopisywania do pliku, o którym wspominałeś, mógłbyś dodać zaraz po tym zapisanie do nowego pliku (nadpisując go - tak by zawsze miał jedną linię z najnowszymi danymi) - wtedy tylko ten plik odczytujesz i po sprawie.

Jeśli nie masz takiej opcji to proponuję:

  1.  
  2. $maxLineSize = 12345; // dlugosc maksymalnej linii z nadkładką (1,5 razy itp.)
  3. $size = filesize('plik.txt','r');
  4. $file = fopen('plik.txt');
  5. fseek($file,$size - $maxLineSize);
  6. $line = fgets($file, $maxLineSize);
  7. fclose($file);
  8. $data = end(explode("\n",$file));
  9.  
  10. echo $data;


Albo jakoś tak smile.gif

EDIT: to jedynie idea - trzeba by ją zabezpieczyć np przed tym że rozmiar pliku jest mniejszy od $maxLineSize itd. itp. smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.