Marcin Pigłowski

Marcin Pigłowski Specjalista ds. baz
danych

Temat: Szybki odczyt plików tekstowych

Chcę napisać program do analizowania plików tekstowych zawierających logi pracy osób korzystających z jakiegoś tam systemu.

Program ma do przetworzenia kilkadziesiąt plików, które łącznie ważą jakieś 4 giga. Wyświetla takie dane jak kto pracował i w jakich godzinach (początek i koniec). Osoba analizująca tą pracę wybiera jeden taki wpis i wyświetla sobie zapis pracy (może być nawet i powyżej 500 mega).

Mój pomysł rozwiązania tego problemu jest taki:
1. odczytuje wszystkie pliki po kolei szukając wpisów z początkiem i końcem pracy użytkownika i zapisuje te dane na jakiejś liście łącznie z nazwami plików, które zawierają logi danej osoby i to wyświetlam.
2. Po wybraniu osoby, której logi chce przeglądać odczytuje dane z wybranych plików i zapisuje do pliku tymczasowego i następnie wyświetlam dane z niego i podczas analizy również cały czas działa na nim. Raczej zaczytanie do pamięci ram odpada bo jednak 500 mega to troche dużo szczególnie, że może być wczytanych kilka osób naraz.

I teraz moje pytanie czy to dobry sposób rozwiązania tego problem?
Czy może jest jakieś lepszy sposób? Czy użyć StreamReadera czy może jest coś szybszego (powiem szczerze, że mam małe doświadczenie w operacjach na tak dużych plikach). Czy wszystko niech działa w głównym wątku czy użyć Threadów lub BackgroundWorkerów?

Będę wdzięczny za pomoc.
Z góry dziękuję.
Jerzy M.

Jerzy M. C#/JavaScript
Developer

Temat: Szybki odczyt plików tekstowych

Czytanie dużej ilości plików samo z siebie pooootrwa, a jak jeszcze budować coś na ich podstawie...

Ale jeżeli rozumiem cel, to sensownie by było dzielić logi na pliki wg. nazwy osoby oraz daty. Albo nawet zapisywać to w bazie danych zamiast plikach .txt Tyle, że chodzi o odczytywanie efektów pracy innego programu?

konto usunięte

Temat: Szybki odczyt plików tekstowych

Marcin Pigłowski:
Chcę napisać program do analizowania plików tekstowych zawierających logi pracy osób korzystających z jakiegoś tam systemu.

Program ma do przetworzenia kilkadziesiąt plików, które łącznie ważą jakieś 4 giga. Wyświetla takie dane jak kto pracował i w jakich godzinach (początek i koniec).

Jaki jest format takiego pliku, przykładowa linia.

2. Po wybraniu osoby, której logi chce przeglądać odczytuje dane z wybranych plików i zapisuje do pliku tymczasowego i następnie wyświetlam dane z niego i podczas analizy również cały czas działa na nim.

IMHO bez sensu. Po co plik tymczasowy, skoro do wyswietlania, przeszukiwania danych i tak musza one byc w pamieci, gdzie mozna je dobrze ulozyc, np. w jakims hashu z kluczem po loginach.

Druga sprawa jak masz zmiar "dzialac" na tych danych? Czy bedziesz je zmieniac, a nastepnie z powrotem wrzucac do oryginalnego logu?
Czy może jest jakieś lepszy sposób? Czy użyć StreamReadera czy może jest coś szybszego (powiem szczerze, że mam małe doświadczenie w operacjach na tak dużych plikach).

StreamReader powinien byc ok.
Czy wszystko niech działa w głównym wątku czy użyć Threadów lub BackgroundWorkerów?

Jesli zrobisz to w glownym watku to na czas odczytu duzych plikow GUI moze zawisnac zatem najlepiej zrobic to w oddzielnym watku. Jesli nie masz doswiadczenia z programowaniem wielowatkowym to najlepiej jest uzyc BeginInvoke() z GUI i delegatem, który odczyta plik. Ew. ThreadPool.QueueUserWorkItem, ew FileStream, który ma asynchroniczne metody odczytu, ale to są już troche bardziej zaawansowane tematy.

A tak w ogóle, to nie prościej to systematycznie wrzucać jakimś importerm do bazy i odpytywać bazę?Sergiusz B. edytował(a) ten post dnia 04.03.10 o godzinie 19:35
Wojciech Z.

Wojciech Z. Konsultant
IT/Biznesowy

Temat: Szybki odczyt plików tekstowych

Ja coś takiego kiedyś robiłem tyle że chodziło o message z mq zrzucane do plików tekstowych - masa małych pliczków - złośliwe.

a) Jeśli interesują cię konkretne pliki i masz jakąś maszynę wolną to nie jest źle zaindexować je w bazie danych po jakichś kryteriach - np. "wpisy użytkownika X w plikach 001, 003, 243 ... itd. Tyle że musisz dopisać jakiś job który będzie cyklicznie czesał nowe pliki i przyrostowo je indeksował.

b) StreamReader jest ok.

c) Jedyny oczywisty sposób żeby to przyspieszyć to pracować na wątkach, jedyny problem jest taki że musisz to dobrze wymierzyć - kilka wątków czytając z dysku będzie sobie przeszkadzać i się blokować, więc jeśli odczyt jest dłuższy niż szukanie w pliku to może niech jeden wątek czyta, a reszta podzieli plik na części i przeczesuje w tym czasie - to się ładnie zrównolegli.

konto usunięte

Temat: Szybki odczyt plików tekstowych

Wojciech Z.:
a) Jeśli interesują cię konkretne pliki i masz jakąś maszynę wolną

Po co od razu wolna maszyna, Sql Express można uruchamiać na kliencie, ew. Sql Compact.

(..) Tyle że musisz dopisać jakiś job który będzie cyklicznie
czesał nowe pliki i przyrostowo je indeksował.

A...pole "id" int unique autoincrement w tabeli nie wystarczy ? :)
Wojciech Z.

Wojciech Z. Konsultant
IT/Biznesowy

Temat: Szybki odczyt plików tekstowych

Ad 1 - można ale pytanie o wydajność, czy baza będzie się rozrastać (przy pisaniu tam danych, przy indexowaniu) i dostępność parsera na wielu maszynach. Poza tym patrz niżej.

Ad 2 - nie bardzo sobie to wyobrażam, może czegoś nie rozumiem... Mamy pliki logów które przyrastają (powiedzmy 1/dzień, 10 mega). Co tu pomoże sekwencja na ID ? Trzeba mieć job który te pliki zaczyta do bazy - całe, lub wybrane informacje z tych plików. A żeby mieć w miarę aktualne dane trzeba to robić cyklicznie.

konto usunięte

Temat: Szybki odczyt plików tekstowych

import do bazy danych jest najbardziej logicznym i sensownym rozwiązaniem, bazę zawsze można doinstalować wraz z aplikacją

zaś samo wyszukiwanie w bazie za pomocą SELEC-ta jest o wiele wydajniejsze niż jakieś domowe sposoby, nie mówiąc o aspekcie elastyczności

co do danych - zawsze można po imporcie zrobić agregat, dane importowane wywalić i tak w koło

konto usunięte

Temat: Szybki odczyt plików tekstowych

Wojciech Z.:
Co tu pomoże sekwencja na ID ?

Nie wiem, próbuje zrozumieć co miałeś na myśli pisząć o jobie, który "przyrostowo indeksuje pliki".

Tak czy inaczej niech autor się wypowie czy mu pasuje wariant z bazą czy trzeba dalej kombinować.
Wojciech Z.

Wojciech Z. Konsultant
IT/Biznesowy

Temat: Szybki odczyt plików tekstowych

Mam problem z precyzyjnym wyrażaniem myśli - jeśli logi nie są kasowane, to job importuje oczywiście tylko przyrostowo, pliki z okresu od rozpoczęcia ostatniego importu.
Dariusz Kumorek

Dariusz Kumorek Programista C# -
www.kumorek.bbnd.eu

Temat: Szybki odczyt plików tekstowych

Hej
Jeśli chciałbyś robić strukturę dla pkt pierwszego, to mogę zaproponować indeks odwrócony + jego niewielka modyfikacja
Ogólnie jest on wykorzystywany do indeksowania plików.
Marcin Pigłowski

Marcin Pigłowski Specjalista ds. baz
danych

Temat: Szybki odczyt plików tekstowych

Dobrze trochę to uporządkuje, bo chyba moja pierwsza wypowiedź była trochę chaotyczna i nie do końca uzyskałem to co chciałem :)

Po pierwsze nie ma możliwości przerobienia mechanizmu tak, żeby zapisywał do bazy i chyba nie ma sensu. Po drugie pomysł, żeby w jobie przepisywać do bazy też odpada bo ilość analizowanych logów do ich całkowitej ilości to może kilka procent albo nawet i mniej.

To jest tak jest zaczytujemy logi z jakiegoś okresu czasu np. dwóch godzin (przykładowo 4 gb). W tym czasie w systemie pracowało powiedzmy 50 użytkowników i tą listę wyświetlamy (razem z godziną rozpoczęcia i zakończenia pracy) w pierwszym kroku działania programu. Drugi etap to analiza czyli wyświetlenie całego zapisu pracy i ewentualnie na życzenie statystyk, czyli ile trwała operacja ile danych zostało zmodyfikowanych.

Wygląd logów to mniej więcej taka struktura:

Data_ropoczecia_akcji Id_uzytkownika Nazwa_akcji
Parametr_akcji_1
Parametr_akcji_2
...
Parametr_akji_n
Data_zakonczenia_akcji Id_uzytkownika Nazwa_akcji

czyli z tego co na razie wiem to jedyna możliwość to StreamReader i ewentualnie wątki.

konto usunięte

Temat: Szybki odczyt plików tekstowych

może nie odkrywajmy koła na nowo ;)

http://www.iis.net/downloads/default.aspx?tabid=34&g=6...
Łukasz Ładoń

Łukasz Ładoń Senior Software
Developer, VSoft
S.A.

Temat: Szybki odczyt plików tekstowych

Jeśli idzie o wyszukiwanie danych z dużej ilości plików tekstowych to polecam zainteresowanie się biblioteką Lucene.net

http://lucenetutorial.com/

konto usunięte

Temat: Szybki odczyt plików tekstowych

Marcin mam do Ciebie prośbę: zainstaluj .NET 4.0 i powiedz, czy nowa funkcja File.ReadLines jest warta zachodu.
Oczywiście ona została stworzona aby stanowić konkurencję dla File.ReadAllLines; skoro Ty pracujesz na Stream'ach nie spodziewam się rożnicy ale jak masz możliwość to zrób test.

Test przeprowadzony na produkcyjnym kodzie jest bardzo wartościowy, stąd prośba.

Następna dyskusja:

szybki hosting




Wyślij zaproszenie do