Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Praca na dużych plikach tekstowych, analiza linia po linii, jak zrobić to możliwie najmniej zasobożernie?
Avatarus
post 5.04.2012, 19:07:34
Post #1





Grupa: Zarejestrowani
Postów: 304
Pomógł: 0
Dołączył: 12.12.2006
Skąd: Pszów

Ostrzeżenie: (0%)
-----


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


--------------------
Go to the top of the page
+Quote Post
zegarek84
post 5.04.2012, 21:00:12
Post #2





Grupa: Zarejestrowani
Postów: 1 332
Pomógł: 294
Dołączył: 12.10.2008
Skąd: Olkusz

Ostrzeżenie: (0%)
-----


fgets...

plik wcześniej na serwer zostanie cały wczytany i potem go obsługujesz...


--------------------
Jeśli twoja ręka rusza do przodu powstrzymaj swój gniew; gdy wyprzedza cię twój gniew - wycofaj rękę.

Go to the top of the page
+Quote Post
Avatarus
post 6.04.2012, 08:12:07
Post #3





Grupa: Zarejestrowani
Postów: 304
Pomógł: 0
Dołączył: 12.12.2006
Skąd: Pszów

Ostrzeżenie: (0%)
-----


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


--------------------
Go to the top of the page
+Quote Post
rocktech.pl
post 6.04.2012, 08:17:50
Post #4





Grupa: Zarejestrowani
Postów: 587
Pomógł: 131
Dołączył: 8.02.2010

Ostrzeżenie: (0%)
-----


Witam.

Zerknij tu SplFileObject.


--------------------
Despite the tons of examples and docs, mod_rewrite is voodoo. Damned cool voodoo, but still voodoo. --Brian Moore

I never go looking for a sucker. I look for a Champion and make a sucker of of him. --Amarillo Slim


Home-made : js-gui-classes | Accordion | Tabs | Carousel / php-sms-classes | Obsługa bramki SMS MultiInfo | Obsługa bramki SMS Mobiltek
Go to the top of the page
+Quote Post
Pilsener
post 6.04.2012, 08:42:32
Post #5





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
Avatarus
post 7.04.2012, 11:10:36
Post #6





Grupa: Zarejestrowani
Postów: 304
Pomógł: 0
Dołączył: 12.12.2006
Skąd: Pszów

Ostrzeżenie: (0%)
-----


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?


--------------------
Go to the top of the page
+Quote Post
Pilsener
post 7.04.2012, 14:29:00
Post #7





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
prowseed
post 7.04.2012, 14:37:48
Post #8





Grupa: Zarejestrowani
Postów: 433
Pomógł: 64
Dołączył: 29.01.2011
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Albo stream_get_line albo tak jak @rocktech.pl napisal
  1. $file = new SplFileObject("plik.txt");
  2. $file->seek( 20 );
  3. return $file->current();


--------------------
Go to the top of the page
+Quote Post
Crozin
post 7.04.2012, 14:57:24
Post #9





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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?
Go to the top of the page
+Quote Post
Avatarus
post 7.04.2012, 17:15:39
Post #10





Grupa: Zarejestrowani
Postów: 304
Pomógł: 0
Dołączył: 12.12.2006
Skąd: Pszów

Ostrzeżenie: (0%)
-----


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.


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 6.05.2025 - 08:33