Odczyt pliku tekstowego problem

0

Witam, mam taki kod ktory odczytuje linie z pliku, tylko jest jeden problem seek nie działa.. chce zaczac czytac od konkretnie określonej lini ...

 
var
x:textfile;
data:string;
i:integer;
begin
assignfile(x,'god32.txt');
reset(x);
seek(x,999); // <---error
for i:=0 to 99 do begin richedit1.Lines.Add(data); readln(x,data); end;
closefile(x);
end;

czym zastąpić seek ?

0

Użyj TStrings.

0
var
  SL: TStringList;
  i, Start, Ile: Integer;
begin
  SL:= TStringList.Create;
  try
  Start:= 999;
  Ile:= 100;
  SL.LoadFromFile('d:\test.txt');
  for i:= Start to Start + Ile -1 do
    RichEdit1.Lines.Add(SL.Strings[i]);
  finally
  SL.Free;
  end;
end;
0

dzieki kazek za kod, ale to wczytuje cały plik do pamieci... a tego nie chce robić.

0

pomyliłem sie to nie wczytuje calego pliku do pamieci, ale i tak zamula z plikiem wielkosci ponad 4GB... kiedys mialem inna metode ale juz nie pamietam jak to robilem. :/

0

plik tekstowy 4Gb. hmmm...

0

No to chyba możesz zrobić tak:

Procedure TFSeek(var F: TextFile; Const Line: Integer);
Var I: Integer;
    Tmp: String;
Begin
 For I := 1 To Line Do
  ReadLn(F, Tmp);
End;

(przyjmując, że wskaźnik pliku jest na początku).

0

w tym pliku jest 200 mln liń , takze nie wiem czy ten kod bedzie optymalny.

0
prob333 napisał(a)

z plikiem wielkosci ponad 4GB.

prob333 napisał(a)

w tym pliku jest 200 mln liń

chcesz powiedzieć, że każda linia ma 20 tyś. znaków?
i to ma być plik tekstowy? smutne…

0

Jeszcze możesz wypróbować http://gp.17slon.com/gp/gptextfile.htm ja tego nie testowałem.

0

Pliki tekstowe o tak dużej wadze są uciążliwe, bo obsługa ich jest czasochłonna; Jeżeli taki plik generowany jest za pomocą Twojego programu - zrezygnuj z tego typu... Są przecież pliki amorficzne i typowane, których obsługa jest bardziej poręczna i elastyczna;

prob333 napisał(a)

dzieki kazek za kod, ale to wczytuje cały plik do pamieci... a tego nie chce robić.

Główna wada - żeby odczytać ostatnią linię pliku, musisz albo wczytać całą zawartość pliku do macierzy / listy lub odczytywać po kolei każdą linię, aż natrafisz na tą, która Cię interesuje; Rozwiązanie bardzo długotrwałe; Przy rozmiarach pliku rzędu kilku gigabajtów - czas odczytu znacznie się wydłuża, a jeśli do tego dojdzie efekt fragmentacji pliku - powodzenia życzę;

prob333 napisał(a)

w tym pliku jest 200 mln liń , takze nie wiem czy ten kod bedzie optymalny.

Optymalne jest zastosowanie pliku typowanego - prostota obsługi powinna Cię zachęcić; Poza tym można bardzo łatwo obliczyć pozycję linii w pliku i tam właśnie przenieść kursor; To chyba jest o wiele szybsze, niż odczytywanie każdej linii z osobna; Poza tym nie liń, tylko linii; Ortografia się kłania;

Mam tylko jedno pytanie - Dlaczego żaden z postujących pomagierów nie zwrócił uwagi autorowi wątku, że procedura Seek() nie może być wykorzystana w plikach tekstowych...?! Smutne, że nikt o tym nie pamiętał:

Funkcja Seek działa jedynie w odniesieniu do plików amorficznych i służy do przechodzenia do określonego miejsca pliku (definiowanego przez użytkownika).
Cytat z książki Delphi 7 - Kompendium programisty; Tak nawiasem pisząc - Seek to procedura, nie funkcja;

To tyle, jeżeli chodzi o generowanie tego pliku własnym programem; Jeśli jednak plik został wygenerowany przez inną aplikację nie pozostaje nic więcej, tylko odczytywać każdą linię, aż do szukanej tak, jak wspomnieli koledzy powyżej (no i ewentualnie nakłonienie autora tamtej aplikacji, aby zmienił sposób zapisu danych do pliku);

0

Dlaczego żaden z postujących pomagierów nie zwrócił uwagi autorowi wątku, że procedura Seek() nie może być wykorzystana w plikach tekstowych...

Kolejny wymysł dziwnych ludziów, oczywiście że się da, wystarczy poszukać w google i jestem pewien że znajdziecie jakiegoś koda.

Poza tym można bardzo łatwo obliczyć pozycję linii w pliku i tam właśnie przenieść kursor

Powiedz mi jaki typ zastosowałeś... file of string[255]? To nie zmieści ci się ponad 255 znaków a inaczej będziesz miejsce marnować... Bez sensu!

Główna wada - żeby odczytać ostatnią linię pliku, musisz albo wczytać całą zawartość pliku do macierzy / listy lub odczytywać po kolei każdą linię, aż natrafisz na tą, która Cię interesuje

Nie prawda, ja bym czytał od końca do #13 a potem z powrotem i tadam, ostatnia linia... Gorzej gdybym miał znaleźć linie na środku pliku! Bym cały musiał i tak przeczytać (żeby znaleźć środkową linię).

Są przecież pliki amorficzne i typowane, których obsługa jest bardziej poręczna i elastyczna;

Wybaczysz, ale czy to nie to samo? :P

Najlepsze rozwiązanie jeżeli o liniach nie można nic powiedzieć ciekawego to zastosowanie formatu (może to nawet być na zwykłym text) gdzie po #13 znajdowałby się numer linii, sądzę ze wtedy możnaby zgadywać gdzie jest linia a potem poprawiać domysły i tak aż się jej nie znajdzie, już nie mówiąc o zapamiętywaniu pozycji dalszych linii żeby przyśpieszyć wyszukiwanie...

0
-pB_No- napisał(a):

Kolejny wymysł dziwnych ludziów, oczywiście że się da, wystarczy poszukać w google i jestem pewien że znajdziecie jakiegoś koda.

Może źle się wyraziłem, da się, ale pod warunkiem, że zmienna plikowa nie jest typu TextFile; Plik tekstowy tak jak i wszystkie inne jest plikiem binarnym, więc można go otworzyć jako taki, stąd da się;

-pB_No- napisał(a):

Powiedz mi jaki typ zastosowałeś... file of string[255]? To nie zmieści ci się ponad 255 znaków a inaczej będziesz miejsce marnować... Bez sensu!

Nie zastosowałem żadnego, nie ja piszę program; Przy ShortString wiadome, że się nie zmieści, ale autor nie napisał ile znaków może posiadać każda z linii, stąd można jedynie spekulować, co w tym przypadku będzie lepsze, a co gorsze; Marnować miejsce? Ciekawe, co odpowiedzieli by Ci autorzy XML'a, jak byś im to zarzucił;

-pB_No- napisał(a):

Nie prawda, ja bym czytał od końca do #13 a potem z powrotem i tadam, ostatnia linia...

Tak? To ciekawe; No i pewnie napisał byś dwa osobne algorytmy, które sprawdzały by czy linia jest przed połową pliku, czy za i odpowiednio czytała by od początku / końca pliku? Bezsens; Poza tym jeśli chciałbyś sprawdzić pozycję linii w pliku to musisał byś znać ich liczbę, czyli i tak trzeba by przeczytać cały plik;

-pB_No- napisał(a):

Wybaczysz, ale czy to nie to samo?

To samo? Wybacz, ale nie; Pliki amorficzne to tzw. pliki binarne, czyli deklaracja zmiennej plikowej jest typu File; Plik typowany zaś to taki, który deklarowany jest specjalną konstrukcją File of TRecordName; Przede wszystkim pliki amorficzne mają nieregularną budowę, czego o typowanych już powiedzieć nie można; Dalej twierdzisz, że to to samo?

-pB_No- napisał(a):

Najlepsze rozwiązanie jeżeli o liniach nie można nic powiedzieć ciekawego to zastosowanie formatu (może to nawet być na zwykłym text) gdzie po #13 znajdowałby się numer linii, sądzę ze wtedy możnaby zgadywać gdzie jest linia a potem poprawiać domysły i tak aż się jej nie znajdzie, już nie mówiąc o zapamiętywaniu pozycji dalszych linii żeby przyśpieszyć wyszukiwanie...

Może i tak, może i nie, ale zgadywanie lepiej zostawić w spokoju, bo na to miejsca nie ma; W każdym razie można by się nad tym zastanowić; Pomysł raczej dobry (jeśli plik generowany jest przez własny program);

Równie dobrze można jechać w pętli po każdym odczytanym znaku z pliku i liczyć znak #13, aż do szukanego i wtedy przeczytac całą linię; Rozwiązań jest kilka, ale i tak przy kilkugigabajtowych plikach będzie to chwilę trwało...

0

Może źle się wyraziłem, da się, ale pod warunkiem, że zmienna plikowa nie jest typu TextFile; Plik tekstowy tak jak i wszystkie inne jest plikiem binarnym, więc można go otworzyć jako taki, stąd da się;

No własnie da się bez zamykania/otwierania pliku... triki... Poszukaj a znajdziesz

Nie zastosowałem żadnego, nie ja piszę program; Przy ShortString wiadome, że się nie zmieści, ale autor nie napisał ile znaków może posiadać każda z linii, stąd można jedynie spekulować, co w tym przypadku będzie lepsze, a co gorsze; Marnować miejsce? Ciekawe, co odpowiedzieli by Ci autorzy XML'a, jak byś im to zarzucił;

No jak będziesz mieć dwu znakowe zmienne w pliku typu ShortString to to będzie marnowanie miejsca. Nie rozumiem co ma XML do tego... hm. JSON i tak lepsze :D

Tak? To ciekawe; No i pewnie napisał byś dwa osobne algorytmy, które sprawdzały by czy linia jest przed połową pliku, czy za i odpowiednio czytała by od początku / końca pliku? Bezsens; Poza tym jeśli chciałbyś sprawdzić pozycję linii w pliku to musisał byś znać ich liczbę, czyli i tak trzeba by przeczytać cały plik;

Dwa osobne? No bez przesady. Już raz coś podobnego pisałem więc tego bym użył. Zwłaszcza że mówiłeś o przypadku gdzie chodzi o ostatnią linię, a zakładając duże pliki można się o to pokusić.
Co do pozycji linii, to pół na pół. Mówiłem że żeby wyznaczyć ilość linii trzeba wszystko przeczytać. ale jeżeli chodzi o pierwszą linię to wiadomo że jest na początku, prawda? Więc twoja odpowiedź jest niedokładna.

To samo? Wybacz, ale nie; Pliki amorficzne to tzw. pliki binarne, czyli deklaracja zmiennej plikowej jest typu File; Plik typowany zaś to taki, który deklarowany jest specjalną konstrukcją File of TRecordName; To samo? Zapytaj kompilator;

File nie jest plikiem binarnym (przynajmniej FPC tak mówi). Dlaczego? Bo jeżeli próbuję robić ReadBlock na File, to dzieje się magia, a jeżeli file of boolean to wszystko jest w porządku. Więc hmhm, ja bym uważał z tym :-] . Ale oczywiście pod Delphi może to inaczej wyglądać, stąd zgoda.

Może i tak, może i nie, ale zgadywanie lepiej zostawić w spokoju, bo na to miejsca nie ma; W każdym razie można by się nad tym zastanowić; Pomysł raczej dobry (jeśli plik generowany jest przez własny program);

Chodziło mi o zgadywanie a na koniec sprawdzanie w której linii jesteśmy i poprawianie domysłów i na tej podstawie szukanie dalsze, powinno być szybsze niż czytanie ciurkiem.

Równie dobrze można jechać w pętli po każdym odczytanym znaku z pliku i liczyć znak powrotu karetki, aż do szukanego i wtedy przeczytac całą linię; Rozwiązań jest kilka, ale i tak przy kilkugigabajtowych plikach będzie to chwilę trwało...

Można nawet do tego BlockRead użyć i innych magicznych sztuczek, tylko wątpie czy to będzie wystarczająco szybkie :P .

0
-pB_No- napisał(a):

No jak będziesz mieć dwu znakowe zmienne w pliku typu ShortString to to będzie marnowanie miejsca.

No tak, racja, ale nie wiemy jeszcze co dokładnie jest zapisywane w pliku, więc ciężko napisać najbardziej optymalne rozwiązanie; Może każda z linii ma tyle samo znaków, a może nie; Może można obliczyć pozycję początku linii bez czytania jego całego, może nie... Trudno cokolwiek napisać, jak nie znamy szczegółów;

Jeśli chodzi o pliki XML'a - na pewno widziałeś nie raz zawartość takiego pliku, więc domyśl się o co mi chodziło :]

-pB_No- napisał(a):

Mówiłem że żeby wyznaczyć ilość linii trzeba wszystko przeczytać. ale jeżeli chodzi o pierwszą linię to wiadomo że jest na początku, prawda? Więc twoja odpowiedź jest niedokładna.

No to jeżeli trzeba i tak przeczytać cały plik, to zbytnio nie ma sensu tego komplikować; Jeśli linia jest na początku pliku, to szybciej będzie normalnie "ciurkiem" go czytać, niż najpierw obliczyć ilość linii, a potem się zastanawiać z której strony się do niego zabrać; Jeśli pisałeś już kiedyś takie coś, to napisz więcej szczegółów;

-pB_No- napisał(a):

File nie jest plikiem binarnym (przynajmniej FPC tak mówi). Dlaczego? Bo jeżeli próbuję robić ReadBlock na File, to dzieje się magia, a jeżeli file of boolean to wszystko jest w porządku.

File jest słowem kluczonym, które oznajmia, że zmienna plikowa o tym typie będzie określać sposób odczytywania / zapisu informacji; Dzięki temu kompilator będzie wiedział jakich operacji można dla tego pliku dokonać, a jakich nie; Stąd o Seek krzyczy; Wiadome, są sztuczki i inne cuda, ale trzymajmy się książkowych zasad; Piszemy o innych kompilatorach, więc się chyba nie dogadamy :P

-pB_No- napisał(a):

Można nawet do tego BlockRead użyć i innych magicznych sztuczek, tylko wątpie czy to będzie wystarczająco szybkie

Oczywiście, że można; Trzeba rozważyć jak najwięcej możliwości i przetestować każdą z nich by wyznaczyć najszybszą; Z resztą z reguły znajdzie się sposób na to, by jakiś algorytm przyspieszyć nawet, gdy wydaje się, że szybciej się już nie da :]

Poczekajmy na odpowiedź autora, może poda jakieś cenne wskazówki;

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