2010-12-17 12 views
5

Scenariusz:Rzuca kosztowną operację?

  • ja analizowania dużego pliku (plik znakowy). Na przykład plik .csv (niezupełnie mój przypadek)
  • Nie mogę zatrzymać całego pliku w pamięci. Muszę więc wdrożyć strategię buforowania.
  • Chcę zbudować ogólny program obsługi, który będzie utrzymywał stałą liczbę linii w pamięci (jako ciągi znaków). Ten moduł obsługi pobiera w razie potrzeby inne wiersze, usuwając niepotrzebne wiersze.
  • Przez ten przewodnik zbuduję parser, który przekształci linie w obiekty Java i będzie obsługiwał zmiany na tych obiektach. Po wprowadzeniu zmian (zaktualizuj niektóre pola na obiektach) kontynuuj zmiany z powrotem do pliku.

Mam:

  • Zamiast zachować bufor jako tablica ciągów, należy zachować bufor bezpośrednio jako obiekty (doing pojedynczy cast)? lub ...
  • Zachowaj bufor jako linie, za każdym razem, gdy muszę operować na buforze, rzuć informacje do odpowiedniego obiektu, wykonaj zmiany, zachowaj zmiany z powrotem do pliku. Sekwencyjne operacje będą wymagać dodatkowych rzutów.

Będę musiał zachować rzeczy proste. Jakieś sugestie?

+1

Jak dokładnie przesyłasz ciągi do innych typów danych? –

+1

mówisz o rzucaniu lub analizie? – fortran

+0

To bardziej skomplikowane. Nie jest to dokładnie rzutowanie z/do String, istnieje wiersz interfejsu i więcej implementacji. Każda implementacja jest jak kontener, który zwraca obiekt. Ten obiekt musi zostać rzucony. Jeśli muszę wprowadzić pewne zmiany w określonym wierszu, potrzebne są pewne rzutowania w wewnętrznym mechanizmie. –

Odpowiedz

8

Rzutowanie nie zmienia ilości pamięci zajmowanej przez obiekt. Po prostu zmienia typ środowiska wykonawczego.

Jeśli możesz wykonywać te operacje w trybie pojedynczego rzędu, po prostu wykonaj operację bezpośrednio w pętli, w której czytasz pojedynczą linię.

while ((line = reader.readLine()) != null) { 
    line = process(line); 
    writer.println(line); 
} 

W ten sposób za każdym razem otrzymujesz tylko jedną linię w pamięci Java zamiast całego pliku.

Lub jeśli chcesz wykonać te operacje w oparciu o cały plik CSV (tj. Te operacje są zależne od wszystkich wierszy), wtedy najbardziej efektywnym zakładem jest zaimportowanie pliku CSV do prawdziwej bazy danych SQL, a następnie użyj instrukcji SQL, aby zmienić dane, a następnie ponownie wyeksportuj je do pliku CSV.

3

Zalecam użycie MappedByteBuffer (z NIO), za pomocą którego można odczytać plik za duży, aby zmieścił się w pamięci. Mapuje tylko region pliku do pamięci; kiedy skończysz czytać ten region (powiedzmy pierwsze 10k), zamapuj następny i tak dalej, aż przeczytasz cały plik. Pamięć jest wydajna i łatwa do wdrożenia.

2

Java odlewnictwa: jak

Object a = new String(); 
String b (String) a; 

nie są drogie. - Nie ważne, czy rzucisz struny czy jakikolwiek inny typ.

1

Twoja prawdziwa wartość dodana będzie czytać każdą linię jako ciąg, co jest dość łatwe w Javie.Po to w ciągu, to jest trywialne, aby podzielić ciąg na każdym przecinkiem z

String[] row = parsedRow.split(",");

woli masz ciąg dla każdej wartości w tablicy, które następnie mogą być obsługiwane na.

+0

Zastanów się, jakie wywołanie 'split()' zrobi na '123," abc, def ", ghi'. –

+0

@JUST MY correct OPINION - należycie odnotowano, ale potem zaczynasz wchodzić w skrajną sprawę, biorąc pod uwagę mój uproszczony przykład, który zakłada, że ​​przecinek zawsze będzie separatorem i nigdy nie będzie zawarty w ciągu znaków. – bakoyaro

Powiązane problemy