Wczytanie bardzo dużego pliku txt

0

Witam,

Mam pewien problem związany plikiem txt o rozmiarze 10 GB (zawiera 181 milionów linii tekstu). Pliku takiego nie da się otworzyć standardowym edytorem tj. notepad czy Notepad++. W związku z tym chciałem wczytać go programowo i podzielić na kilkadziesiąt mniejszych plików, które następnie będzie można przejrzeć i poddać dalszej analizie. Problemem jaki mam jest czas potrzebny na podział. Próbowałem różnych strategii: włącznie z czytaniem pliku przez wiele wątków niezależnie od siebie (tzn. jeden wątek wczytuje i dzieli część od linii 0 do linii 100 000, drugi od 100 001 linii do 200 000 linii itd). W przypadku pracy na wielu wątkach widać pewne przyspieszenie, ale wciąż czas potrzebny na przetworzenie takiej ilości danych jest strasznie długi (na mocnej maszynie wyszło mi że musiałbym czekać na wynik kilka dni). Czy istnieje jakaś opcja, która pozwoliłaby dokonać takiej operacji w sensownym czasie (np. kilka godzin/1 dzień)? Czy też może należy wykonać takie zadanie w innym języku programowania niż C#?

Pozdrawiam.

0

Myślę, że można by linuxowe dd do tego wykorzystać i mieć w kilka minut gotowe.
Edit: chociaż nie, z tego co wiem liniami nie można, musiałbyś wyczaić offsety.

0

Wątki mogą (choć nie muszą) nawet spowolnić pracę z plikiem. Musisz pamiętać o odpowiedniej wartości FileAccess i FileShare.
Możesz pokazać fragment kodu którym kopiujesz tekst? Jakoś nie chce mi się wierzyć że jest aż tak wolny.

1

Tak z ciekawości stworzyłem program który tworzy duży plik, nie chciało mi się czekać na stworzenie większego ale 18mln linii, zajęło 1.8 Gb pamięci i stworzyło się to w 1min. Więc nie wydaje mi się aby odczyt + zapis był aż tak wolny.

1

Jest kilkanaście sposobów na odczytanie pliku, skąd mamy wiedzieć, którego Ty użyłeś i czemu tak wolno działa, skoro nie pokazałeś kodu?

Sensowny czas tej operacji jest mniejszy niż 10 minut.

0

Uwaga, odpalam swoją magiczną kulę!

Skoro dodanie wątków do czytania w wielu miejscach przyspieszyło wykonywanie zadania oznacza to tyle, że wykonujesz operacje na bieŻąco (Boże, widzisz takie błędy i nie grzmisz) dla wczytanych danych blokując wczytywanie.

Jeden wątek zajmuje się czytaniem, drugi pisaniem. Tyle ma się dziać.

3
  1. ustalasz po ile MB chcesz mieć pliki (dalej x MB)
  2. kopiujesz z głównego pliku (dalej g) x MB blokami po np. 1024b
  3. szukasz w g pierwszego znaku nowej linii
  4. do ostatniego pliku x MB doklejasz na końcu resztę ostatniej linii
  5. goto 1 aż skończy Ci się plik g

Na pewno będzie szybsze niż szukanie każdego końca linii i ich zliczanie. Wada to to, że będziesz miał różną ilość linii ale zbliżony rozmiar każdego kawałka

0

Pliku takiego nie da się otworzyć standardowym edytorem tj. notepad czy Notepad++. W związku z tym chciałem wczytać go programowo i podzielić na kilkadziesiąt mniejszych plików, które następnie będzie można przejrzeć i poddać dalszej analizie.

Pytanie na czym ma polegać ta analiza.
Taki klawisz F3 pod Total Commanderem jest w stanie wyświetlić wielki plik.

0

@Azarien, dlaczego Total jest zdolny, a inne edytory nie? Przecież żeby coś wyświetlic konieczne jest włożenie do pamięci, a tyle nie włożymy do pamięci.
podro

0
Złoty Krawiec napisał(a):

@Azarien, dlaczego Total jest zdolny, a inne edytory nie? Przecież żeby coś wyświetlic konieczne jest włożenie do pamięci, a tyle nie włożymy do pamięci.
podro

Nie musisz wkładać od razu do pamięci całego pliku - wystarczy tyle, ile jest wyświetlone na ekranie.

0
Złoty Krawiec napisał(a):

@Azarien, dlaczego Total jest zdolny, a inne edytory nie? Przecież żeby coś wyświetlic konieczne jest włożenie do pamięci, a tyle nie włożymy do pamięci.
podro

bo pod F3 masz PODGLĄD a nie edycję i możesz mieć w pamięci tylko to co pokazujesz nie przejmując się resztą

5

Dla testów napisałem program (ze 30 linijek), który plik 5,88GB podzielił na 1071 plików po 10000 linii w ciągu 686 sekund.
Teraz zastanawiam się, co schrzanić, żeby wydłużyć taką banalną operację do dni.

4

http://linux.die.net/man/1/split

split -l <liczba_linii_per_plik>

0

no, no... R podobno też wysiada przy takich wielkościach. Spróbuj jakoś pod linuxem.

0

Pierwsze pytanie czy rekordy mają spójną strukturę czy są to dane heterogeniczne.
Drugie pytanie jaki rodzaj analizy cię interesuje.


Jeżeli rekordy mają identyczną strukturę to można spróbować je zaciągnąć do bazy danych. Postgres sobie z tym spokojnie poradzi.
Możliwe, że częśc analizy można zrobić za pomocą SQLa.

0
PAV napisał(a):

..o rozmiarze 10 GB (zawiera 181 milionów linii tekstu)....

Możesz wrzucić jakiś fragment tego pliku?

1 użytkowników online, w tym zalogowanych: 0, gości: 1