2012-04-27 19 views
6

Muszę parsować duży plik CSV w czasie rzeczywistym, podczas gdy jest on zmodyfikowany (dołączony) przez inny proces. Przez duże mam na myśli ~ 20 GB w tym momencie i powoli rośnie. Aplikacja musi jedynie wykrywać i zgłaszać pewne anomalie w strumieniu danych, dla których potrzebuje jedynie przechowywać niewielkie informacje o stanie (O(1)).Parsowanie dużych plików tekstowych, zmodyfikowanych w locie

Zastanawiam się nad odpytywaniem atrybutów pliku (rozmiaru) co kilka sekund, otwieraniem strumienia tylko do odczytu, szukaniem poprzedniej pozycji, a następnie kontynuowaniem analizowania miejsca, w którym po raz pierwszy stanąłem. Ale ponieważ jest to plik tekstowy (CSV), oczywiście muszę nadal śledzić znaki nowej linii, aby kontynuować, aby upewnić się, że zawsze parsuję całą linię.

Jeśli się nie mylę, nie powinno to stanowić problemu, ale chciałem się dowiedzieć, czy istnieje wspólna metoda/biblioteka, która rozwiązuje już niektóre z tych problemów?

Uwaga: Nie potrzebuję analizatora składni CSV. Potrzebuję informacji o bibliotece, która upraszcza czytanie linii z pliku, który jest modyfikowany w locie.

+0

Czy można zatrzymać przetwarzanie plików CSV? Jeśli tak, proponuję przeniesienie go do RDBMS. – Oybek

+0

@Oybek: możesz to trochę wyjaśnić? Proces, który jest dołączany do pliku, ciągle działa i muszę analizować linię danych po linii (z kilkuminutowym opóźnieniem). – Groo

+0

Zakładam, że nie masz kontroli nad procesem wysyłania pliku? –

Odpowiedz

1

Jest mały problem tutaj:

  • czytania i analizowania CSV wymaga TextReader
  • Pozycjonowanie nie działa (również) z TextReaders.

Pierwsza myśl: trzymaj ją otwartą. Jeśli zarówno producent i analizator pracuje w trybie niewyłącznej powinno być możliwe readline-aż-null, wstrzymać, ReadLine-aż-null, itp


powinno być 7-bitowe ASCII , tylko niektóre Guids i numery

Umożliwia to śledzenie położenia pliku (pos + = line.Length + 2). Upewnij się, że otworzysz go pod numerem . Możesz ponownie otworzyć go jako zwykły strumień binarny, odszukać do ostatniej pozycji i dopiero wtedy dołączyć StreamReader do tego strumienia.

+0

Masz rację, to chyba o wiele lepiej niż poszukiwanie. – Groo

+0

Crap, w ogóle nie brałem pod uwagę znaków wielobajtowych, dopóki o tym nie wspomniałeś. Kolejna świetna wskazówka, dzięki! – Groo

0

Po prostu nie rozpoczynamy oddzielnego procesu/wątku za każdym razem, gdy rozpoczynamy parsowanie - w ten sposób przeniesiecie część współbieżną (w locie) z dala od źródła danych i w stronę zlewu danych - tak teraz po prostu trzeba dowiedzieć się, jak zbierać wyniki z wszystkich wątków ...

Ten będzie znaczy robi ponownego odczytania całego pliku dla każdego wątku spin w górę, chociaż ...

Możesz uruchomić program diff na dwóch wersjach i odbierać od niego, w zależności od tego, jak dobrze uformowane jest źródło danych csv: Czy zmienia on już zapisy? A może po prostu dodaje nowe rekordy?Jeśli tak, można po prostu podzielić się nowe rzeczy (w ostatniej pozycji do bieżącej-EOF) do nowego pliku i przetwarza te na wypoczynek w wątku tła:

  • wątek odpytywania zapamiętuje wielkość ostatniego pliku
  • gdy plik robi się coraz większy: poszukiwania z ostatniej pozycji do końca, zapisać do pliku tymczasowego
  • wątek tła przetwarza wszystkie pliki tymczasowe pozostało, w celu stworzenia/modyfikacji
+1

Cóż, rozmiar dołączanych danych w każdej sekundzie jest stosunkowo niewielki w porównaniu do całego rozmiaru pliku, dlatego nie chcę go czytać za każdym razem (może to być 50 GB po tygodniu pomiarów). A ponieważ dane są tylko dołączane, a pliki bardzo duże, różnice nie są praktyczne. Nie rozumiem również części dotyczącej wątków: ponieważ jest to operacja na dysku, czytanie nie będzie korzystało z wielu wątków, może działać tylko wolniej IMO, a krok, w którym piszę częściowy plik na dysk, a następnie otwórz go ponownie również wydaje się zbędny (jeśli go kopiuję, równie dobrze mogę go przeanalizować). – Groo

2

nie testowałem, ale myślę, że może użyć FileSystemWatcher do wykrycia, kiedy inny proces zmodyfikował twój plik. W wydarzeniu Zmienione będziesz mógł szukać wcześniej zapisanej pozycji i przeczytać dodatkową zawartość.

Powiązane problemy