Mam problem z ListView

0

Mój problem tkwi w szybkości odczytu. Mam 4 kolumny i ok. 20 000 pozycji i teraz po włączeniu programu program ładuje się nawet 5 min. Jest może jakaś szybsza metoda odczytu (zapis może długo trwać ale odczyt szybko) ?

Stosuje ReadComponent (TMemoryStream) i kodu do zapisu i odczytu ListView pobranego z torry.net lecz wszystkie te metody nie odnoszą sukcesu.

0

Stosujesz metody BeginUpdate i EndUpdate?

0

Nie pomogło ani w readcomponent ani w tym kodzie z torry. Może zna ktoś innne rozwiązanie?

0

Zrobiłem sobie teścik używając innej metody odczytu z pliku. 20000 linii po 4 kolumny wyświetlało sie 2 min 15 sek na Duronie 850/386 MB. Niestety 20000 to sporo. Może to byc nie do przeskoczenia z TListView. Może inny (własny) komponent? Może nie ładowac wszystkiego na początku, tylko dopiero na żądanie? Może ktoś wpdanie na lepszy pomysł... A może postawić ProgressBara i kazać userowi poczekać?

//o, albo wątek - vide poniżej :-)

Dla porównania, oto mój kod:

  tRow=record
   c1:string[10];
   c2:string[5];
   c3:string[10];
   c4:string[20];
  end;

var
  a: array of TRow;
  f: file of TRow;

//tworzenie i wypelnianie tablicy fikcyjnych danych
 SetLength(a,20000);
 for i:=Low(a) to High(a) do
   begin
    a[i].c1:=IntToStr(i);
    a[i].c2:=IntToStr(Random(65536));
    a[i].c3:=IntToStr(Random($FFFFFFFF));
    a[i].c4:=StringOfChar(Chr(65+Random(20)),2+Random(19));
    
   end;
//zapis do pliku
 AssignFile(F,'test.dat');
 Rewrite(F);
 BlockWrite(F,a[0],Length(a));
 CloseFile(F);


//odczyt z pliku
 AssignFile(F,'test.dat');
 Reset(F);
 SetLength(a,FileSize(F));
 BlockRead(F,a[0],FileSize(F));
 CloseFile(F);


 ProGressBar1.Min:=0;
 ProgressBar1.Max:=High(a);

//do tej chwili leci błyskiem, następna część robi się 2:15

//wyswietlenie
  with ListView1.Items do
  begin
    BeginUpdate;
    for i:=Low(a) to High(a) do
    begin
      it:=Add;
      it.Caption:=a[i].c1;
      it.SubItems.Add(a[i].c2);
      it.SubItems.Add(a[i].c3);
      it.SubItems.Add(a[i].c4);
      if (i and $1f)=0 then begin
       ProgressBar1.Position:=i;
       Application.ProcessMessages;
       end;
    end;
    EndUpdate;
  end;
0

Cześć :)

Na mój chłopski rozum nie powinieneś używać do zapisu ListView jako
całego komponentu , tylko pogłówkować tak by dane zapisać do pliku

  • tak jak leci, czyli liniami
    Następnie zrobić procedurkę odczytu linia po linii i od razu to co odczytane powinno być wyświetlane w ListView.

Najlepiej jakby procedurę odczytu zrobić jako wątek. Wtedy użytkownik
może robić w progsie coś innego (lub dłubać w nosie :) ) a ListView
w miare odczytu danych będzie się uzupełniał.

To jest tylko sugestja , na pewno ktoś znajdzie coś fachowego.

0

A nie ma jeszcze szybszego sposobu bo umnie to nadal wolno idzie poniewać w każdym itemie mam przynajmniej od 80 do 150 znaków nie tylko cyfr ale liter także.

0

Jest szybszy sposób :)
Trzeba ustawić ListView na tryb Virtual (OwnerData := True).
Przykład zastosowania VirtualListView masz w demosach Delphi.

0

hmm mi trochę przyspieszyło załadowanie najpierw całego pliku do memo i wczytywanie do listview z tego memo. "troche" to znaczy przy 10000 rekordach z ok. 5 min do 31 sek. samo załadowanie pliku 1,14MB do memo trwa coś ok. 1 sek.

0

hmm a nie lepiej:

type
   tRow=record
    c1:string[10];
    c2:string[5];
    c3:string[10];
    c4:string[20];
   end;
var
  f: file of TRow;
  Row: TRow;
begin
  //odczyt z pliku
  AssignFile(F,'test.dat');
  Reset(F);
  ListView1.BeginUpdate;
  while not Eof(F) do begin
    Read(F, Row);
    with ListView1.Items.Add do begin
      Caption:=Row.c1;
      SubItems.Add(Row.c2);
      SubItems.Add(Row.c3);
      SubItems.Add(Row.c4);
    end;
  end;
  ListView1.EndUpdate;
  CloseFile(F);
end;

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