2013-03-27 10 views
20

Poszukuję wyjaśnienia, jak działa seekg() i seekp() w odniesieniu do zapisu w pliku. Powiedzmy na przykład, że miałem taki plik:fstream seekg(), seekp() i write()

offset 0: 2 
offset 4: 4 
offset 8: 6 
offset 12: 8 
offset 16: 10 

Teraz chcę otworzyć plik i wykonać pewne czynności, aby odczytać i zapisać wartości.

Teraz chcę napisać na końcu pliku. Ponieważ funkcja seekg() przesuwa tylko kursor wyszukiwania, mój kursor powinien nadal znajdować się na końcu pliku w prawo? Więc:

int newKey = 12; 
file.write((char *) &newKey, sizeof(int)); 

powinien zrobić mój plik teraz wyglądać następująco:

offset 0: 2 
offset 4: 4 
offset 8: 6 
offset 12: 8 
offset 16: 10 
offset 20: 12 

Teraz co się dzieje z moim pliku jeśli wybiorę dążyć do przesunięcia i napisać swoją wartość jako offset do wartości, która była właśnie włożono. Na przykład chcę, aby offset 8 przechowywał eofOffset = 20, ponieważ właśnie wstawiliśmy 12 w tym przesunięciu.

Jeśli zrobić:

file.seekp(8, ios::beg); 
file.write((char *) &eofOffset, sizeof(int)); 

to poprawnie przepisać mój plik powinien wyglądać tak:

offset 0: 2 
offset 4: 4 
offset 8: 20 
offset 12: 8 
offset 16: 10 
offset 20: 12 

Proszę dać mi znać, jeśli robię jakieś błędy za pomocą funkcji seekg() i seekp().

Odpowiedz

21

Klasa szablon std::basic_filebuf posiada pojedynczą pozycję pliku

§ 27.9.1.1

  1. Do klasy stowarzyszone basic_filebuf zarówno wejście sekwencji i sekwencji wyjście z pliku.
  2. Ograniczenia dotyczące odczytu i zapisu sekwencji sterowanej przez obiekt klasy basic_filebuf są takie same, jak w przypadku odczytu i zapisu w bibliotece plików C standardowej biblioteki.
  3. W szczególności:
    • Jeśli plik nie jest otwarty dla odczytu sekwencji wejściowej nie można odczytać.
    • Jeśli plik nie jest otwarty do zapisu, sekwencji wyjściowej nie można zapisać.
    • Pozycja wspólnego pliku jest zachowywana zarówno dla sekwencji wejściowej, jak i sekwencji wyjściowej.

Oznacza to, że podczas korzystania z std::basic_fstream, który domyślnie używa std::basic_filebuf pozycja pojedynczy plik jest przenoszony zarówno przez seekp() i seekg(); chyba że użyjesz oddzielnej zmiennej do przechowywania jednej z pozycji, abyś mógł następnie do niej wrócić, nie możesz śledzić pozycji put i zdobywaj niezależnie.

Konsekwencje punktu 2 polegają na tym, że pomiędzy odczytami i zapisami na fstream należy albo opróżnić bufor, albo wyszukać pozycję pliku przy zmianie z wyjścia na wejście, a użytkownik musi albo znajdować się na końcu pliku, albo szukać pozycja pliku przy zmianie z wejścia na wyjście.

Szczegółowe informacje na temat tych ograniczeń można znaleźć w sekcji 7.19.5.3/7 normy C99 ("Funkcja fopen") lub 7.21.5.3/7 w C11.

+0

Dzięki! Więc kiedy polecasz płukanie bufora? Czy opróżnisz go po każdym czytaniu i pisaniu, czy też będzie w porządku pozostawić go tak, jak robisz serię czytań lub serię pism? – raphnguyen

+1

@raphnguyen Płukanie bufora jest stosunkowo kosztowną operacją, zwykle nie ma potrzeby ręcznego spłukiwania, chyba że zmienisz pisanie na czytanie i nie będziesz szukał, chyba że masz dobry powód do przepłukania, niech implementacja zajmie się innymi kolorami. – user657267

Powiązane problemy