Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Praca na dużych plikach tekstowych, analiza linia po linii
Forum PHP.pl > Forum > PHP
Avatarus
Witam
Mam projekt w którym muszę przeanalizować duże pliki txt które są wgrywane przez formularz na stronę.
Pliki trzeba analizować lina po linii.
Pliki mogą mieć nawet po kilka MB.
Jednocześnie takich analiz może zlecić kilkanaście osób.

Jak to zrobić żeby mi serwer przez to nie padł?
Jakaś skuteczna metoda?

Można np połączyć z ajaxem i czytać po 100 linii, aż do końca pliku? może jakaś inna lepsza metoda?

z góry dziękuje
zegarek84
fgets...

plik wcześniej na serwer zostanie cały wczytany i potem go obsługujesz...
Avatarus
ok. ale pytanie, gdyby plik miał np 20MB to czy fgets musi najpierw te 20MB wczytać do RAM serwera (ktorego mam 512 )
i teraz jak mi tak 50 userów takie coś odpali to serwer padnie.

Czy fgets wczyta tylko ten skrawek pliku który zaznaczę?
rocktech.pl
Witam.

Zerknij tu SplFileObject.
Pilsener
Przecież masz wszystko napisane z przykładami, w dodatku po polsku:
Cytat
Pobiera linię ze wskaźnika pliku.


Ile może mieć maksymalnie bajtów linijka w pliku?
Pierwszy przykład z linku:
  1. //Przykład #1 Oczyt pliku linia po linii
  2. <?php
  3. $uchwyt = @fopen("/tmp/plik_wejsciowy.txt", "r");
  4. if ($uchwyt) {
  5. while (($bufor = fgets($uchwyt, 4096)) !== false) {
  6. echo $bufor;
  7. }
  8. if (!feof($uchwyt)) {
  9. echo "Błąd: niespodziewany błąd fgets()\n";
  10. }
  11. fclose($uchwyt);
  12. }
  13. ?>


Mamy skopiować stamtąd i tu wklejać, bo nie chce się w link kliknąć? thumbsdownsmileyanim.gif
Avatarus
ok tylko jak w tym przykładzie odczytać z pliku który ma np 100 linii, tylko linie od 20-50?
wiem jak to zrobić wrzucając pętlę która przeskoczy wskaźnik o 20, ale takie rozwiązanie nie jest dobre bo i tak i tak będzie wczytać finalnie cały plik.

ja chce to zrobić tak że Ajaxowo będzie co parę sekund wczytywane te kilka linii z tego pliku, obrabiane, zapisywane do bazi i tak w kółko aż skończy obróbkę pliku.

Jak zatem zrobić to żeby pliku np 20MB nie zabiły serwera?
Pilsener
Fragment mojego tutoriala o obsłudze plików:

  1. $uchwyt = fopen($pliczek,'r');
  2. while(!feof($uchwyt)){
  3. $linia = rtrim(fgets($uchwyt));
  4. $licznik++;
  5. if($licznik>$od && $licznik<=$do){
  6. $tabliczka[] = $linia;
  7. }
  8. }
  9. fclose($uchwyt);
- pobiera do tablicy linie o numerach od-do.

Cytat
ja chce to zrobić tak że Ajaxowo będzie co parę sekund wczytywane te kilka linii z tego pliku, obrabiane, zapisywane do bazi i tak w kółko aż skończy obróbkę pliku
- no ale co konkretnie chcesz zrobić? Wrzucić tylko plik do bazy? Czy będziesz wywoływał to co kilka sekund czy od razu nie ma większego znaczenia dla wydajności.

Zakładam, że chodzi o dodanie do bazy jakś danych z pliku - dlatego najlepiej sparsować cały plik linia po linii, utworzyć nowy z interesującymi nas danymi a następnie wrzucić do bazy od razu cały plik zapytaniem LOAD DATA. Robiłem tak z plikami nawet gigabajtowymi i nie było większych problemów z pamięcią, operujesz tylko na linii pliku a import całego pliku do bazy przebiega bardzo sprawnie.

Można też cały plik od razu wrzucać do bazy, do jakiejś tabeli tymczasowej i w ten sposób go obrobić. Wszystko zależy od specyfikacji.
prowseed
Albo stream_get_line albo tak jak @rocktech.pl napisal
  1. $file = new SplFileObject("plik.txt");
  2. $file->seek( 20 );
  3. return $file->current();
Crozin
W przypadku zwykłego pliku tekstowego, nie ma bata, trzeba przelecieć cały plik od początku, sprawdzając znak po znaku czy nie natrafiliśmy aby przypadkiem na wartość odpowiadającą nowej linii (trzeba wziąć poprawkę na sposób zapisu pliku, czy będzie to \n, \r czy \r\n). Jest to więc rozwiązanie bardzo nieefektywne.

Dlaczego nie skorzystasz z bazy danych?
Avatarus
Dzięki już to działa.
Korzystam z metody jaką wskazał prowseed
to rozwiązanie jest najszybsze i najefektywniejsze.
Przerabiałem teraz plik (czytany po 100 linii) z 3 MB pliku i chodzi bardzo płynnie.

Dzięki wielkie za pomoc.
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.