Skocz do zawartości

[Delphi] TStringList, ale do pliku


Brainer

Polecane posty

Witam. :)

 

Mam takie pytanko, czy ktoś natknął się kiedykolwiek na klasę podobną w działaniu do TStringList, ale zamiast przechowywania napisów w pamięci zapisywałaby je od razu do przypisanego pliku/strumienia? Byłbym bardzo wdzięczny za jakieś linki.

 

Lub jeżeli nikt z was nie spotkał nigdy takiej klasy, może mógłbym prosić jakieś drobne sugestie, jak się zabrać do napisania takiej klasy? Głównie to chodzi mi o sposób usuwania napisów z pliku. Jedyny sposób, który przyszedł mi do głowy to przepisywanie całego pliku oprócz stringa, który mamy w planach usunąć. Ale nie wiem jak bardzo jest to wydajne. :unsure:

 

Z góry dziękuję. :)

Link do komentarza
Udostępnij na innych stronach

Nom to nie, definitywnie to nie jest żadne rozwiązanie. Hmm, nom a co z wydajnością? Z tego co wiem, to wszystkie archiwizery typu WinRAR czy WinZIP w ten sposób obsługują usuwanie plików. Nigdy nie próbowałem z dużymi plikami, ale jak szybko to działa? Bo do pewnego projektu potrzeba mi klasy TStringList pracującej na strumieniu... Ale ciężko znaleźć coś takiego...

Link do komentarza
Udostępnij na innych stronach

TStringStream to klasa pracujaca na strumieniach stringowych.

Co do archiwizerow to nie do konca pracuja jak TStringList. Mozesz zrobic podzial chunkowy z offsetami do napisow i inne cuda ale mam wrazenie ze slusznym rozwiazaniem w przypadku pracy sekwencyjnej ze stringami nie jest mapowanie na plik ale uzycie bazy danych, ktora zrobi to za ciebie i to wydajniej nizbys bawil sie dyskiem.

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

Nie Toster, źle mnie zrozumiałeś. :) Chodziło mi o to, w jaki sposób archiwizery usuwają pliki z archiwów.

 

Nom ale czy TStringStream pozwala mi czytać i zapisywać stringi w innym strumieniu (np. w TFileStream)? :unsure:

 

Hmm, możesz powiedzieć coś więcej o tym "chunkowym podziale"?

Link do komentarza
Udostępnij na innych stronach

TStringStream dziedziczy z TStream, używasz go jak każdego strumienia.

 

Co do chunkowego podziału, to myślę, że Tosterowi chodzi o coś w rodzaju VFS -> dzielisz sobie plik na sektory i zapisujesz nowe dane kawałkami w pustych miejscach.

Tyle, że w pewnym momencie dane ci się konkretnie fragmentują i i tak będzie trzeba przepisywać :P

 

Jak będziesz się w to bawił, to nie korzystaj z TFileStream, tylko "Memory mapped files", jest sporo szybsze.

Obrazek
Link do komentarza
Udostępnij na innych stronach

Ah, z tego co pamiętam, to Toster tu kiedyś mały przykład VFSa pokazywał. :) Nom ale stringi też dzielić na chunki?

 

Może to w moim rozumowaniu jest błąd. Listy w Delphi nie są nielimitowane, więc nie mogę przechowywać w nich nieskończonej ilości danych, a projekt, do którego potrzebuje takiej listy miałby zarządzać dużą ilością takich stringów. Toster wspomniał coś o bazie danych - tylko nie słyszałem o żadnej, która pozwoli mi zintegrować jej system z klasą TStream, a to byłoby mi bardzo na rękę. Coś możecie polecić?

Link do komentarza
Udostępnij na innych stronach

Stream to stream, pracujersz na nim z tymi samymi uniwersalnymi zasadami, jedyna roznica miedzy stremami (w wielkim uproszczeniu) to medium na ktorym pracuja, tak wiec

TFileStream - operuje na dysku (na pliku dokladnie rzecz biorac)

TStringStream - operuje na buforze stringowym o ile mnie pamiec nie myli

TMemoryStream - operuje na kawalku pamieci

 

w kazdym obiekcie ktory dziedziczy po TStream praca polega na tych samych zasadach, zerknij do helpa i dem.

 

Nie rozumiem 2 giego pytania,

jak masz kilka strumieni to masz kilka obiektow TStream (lub pochodnych), mozesz dowolnie z nich czytac (i zazwyczaj zapisywac) lub po nich sie przemieszczac (seek), mozesz tez kopiowac porcje danych bezposrednio z jednego streama do drugiego.

 

podzial chunkowy jest dosyc dobrze opisany na sieci ogolna zasada jest taka: masz jakies medium np plik, wrzucasz do niego dane ktore cie interesuja ale nie sa one wrzucone od tak sobie tylko sa podzielone w chunki. Kazdy chunk ma na poczatku header ktory identyfikuje to co jest wazne dla niego. Czyli mozesz np zrobic takie cos:

 

/Chunk/

/Header/

TypDanych, RozmiarDanych

/Body/

dane

 

..... n x takie chunki i wtedy kazda linie tekstu trzymac w ten sposob

w efekcie mozesz dodac flage do headera np Deleted. Wtedy pomimo iz w pliku fizycznie istnieje dany napis (zuzywa tez oczywiscie pamiec) to procedury czytajace sprawdza sobie czy ma flage deleted, jesli tak nie beda czytac body tylko od razu przejda do kolejnego chunka.

 

Mniej wiecej tak dzialaja archiwizery, maja iles tam plikow, zapisuja na poczatku info o pliku + czesto slownik + dane skompresowane. w efekcie usuniecie moze sie wiazac tylko z wywaleniem danego chunka (move danych) a moze sie wiazac z usunieciem chunka + rekompresja reszty, nie pisalem nigdy wiec nie jestem pewien.

 

Mozesz tez zrobic sobie podzial na bloki (podobnie jak robi manager pamieci) np

tworzysz od razu chunk 64kb, i w nim trzymasz podchunki z kolejnymi tekstami, gdy blok jest zapelniony to dodajesz kolejny blok 64k, itd itd. Jesli rozbijesz kazdy blok do osobnego pliku to pozniej mozesz w teorii za jednym zamachem odbudowac strukture z pominieciem skasowanych chunkow.

 

Zerknij na forum kiedys wrzucilem przykladowy filesystem tam masz wytlumaczone i zakodowane to co tutaj jako tako opisuje.

 

EDIT:

Wiekszosc baz danych pozwala na prace strumieniowa, popatrz na komponenty ADO, nie jest proste bez ksiazki/tutka nie ruszysz za daleko ale zawsze mozesz uzyc czystych zapytan sql'a

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

  • 3 weeks later...

Wybaczcie, że odgrzewam ten topic, ale nadal mam pewne wątpliwości, a nawiązują one do tego, co wcześniej w tym wątku poruszono.

 

Otóż postanowiłem trochę poczytać na temat systemów plików (głównie FAT i NTFS) i napotkałem się na strukturę stosowaną w NTFSie, która nazywa się b+drzewo. Poszperałem w internecie na ten temat i jedyne, co zrozumiałem, to to, że jest to drzewo wyważone, a jego struktura jest zoptymalizowana pod kątem jak najmniejszej ilości operacji dyskowych. Jednak, w jaki sposób reprezentuje to hierarchię plików i katalogów? Czy ktoś może mi to jakoś łopatologicznie wyjaśnić?

 

EDIT

Dla przykładu, chciałbym poniższą hierarchię plików zapisać w postaci B+drzewa. Jak to wykonać?

Obrazek

Link do komentarza
Udostępnij na innych stronach

Ok, ponownie odgrzebuję temat, bo może w przyszłości ktoś będzie miał podobny problem, to liczę, że tu odnajdzie pomoc.

 

Otóż dowiedziałem się, że b+drzewa nie są używane do reprezentacji hierarchii, tylko do szybkiego listowania plików i katalogów, zatem każdy katalog ma swoje b+drzewo. Jako że sama struktura wydała mi się za bardzo skomplikowana, odszedłem od pomysłu zastosowania jej w projekcie.

 

Pokombinowałem trochę z SQLite i zaobserwowałem, że tam struktura bazy danych wygląda tak:

Obrazek

 

I to po prostu jest to, co chciałbym zastosować u siebie! :D Ale kompletnie nie wiem, jak takie coś osiągnąć, żeby te obszary rosły ku sobie, nie nachodząc na siebie. :blink:

 

Macie jakiś pomysł? A może całkowicie inny koncept?

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...