2009-05-16 3 views
38

Używam C, aby zapisać niektóre dane do pliku. Chcę usunąć poprzedni tekst zapisany w pliku na wypadek, gdyby był dłuższy niż to, co teraz piszę. Chcę zmniejszyć rozmiar pliku lub skrócić do końca. Jak mogę to zrobić?Jak skrócić plik w C?

Odpowiedz

19

W systemach Windows nie ma nagłówka <unistd.h> ale jeszcze można obciąć pliku przy użyciu

_chsize(fileno(f), size); 
+5

_chsize_s dla 64-bitów: _chsize_s (_fileno (f), rozmiar); – Gyuri

+0

Funkcja _fileno naprawdę pomaga, jeśli używamy struktury FILE – Carthi

+0

Czy to nie jest funkcja MS-Windows ?! –

12

To jest funkcja twojego systemu operacyjnego. Standardowy sposób na POSIX to:

open("file", O_TRUNC | O_WRONLY); 
+6

ta obcina plik o rozmiarze 0 bajtów. – chmike

4

Jeśli chcesz skasować cały plik, otwarcie pliku do zapisu robi to za ciebie. W przeciwnym razie musisz otworzyć plik do odczytu i odczytać fragmenty pliku, które chcesz zachować, do zmiennej tymczasowej, a następnie wypisać je w dowolnym miejscu.

Obciąć cały plik:

FILE *file = fopen("filename.txt", "w"); //automatically clears the entire file for you. 

obciąć część pliku:

FILE *inFile("filename.txt", "r"); 
//read in the data you want to keep 
fclose(inFile); 
FILE *outFile("filename.txt", "w"); 
//output back the data you want to keep into the file, or what you want to output. 
+5

Jest to bardzo nieefektywny sposób wykonania tego. Metoda @ Jonathan'a Lefflera jest znacznie lepsza i jeśli twoja platforma na to nie pozwala, przynajmniej wykonaj cykl zapisu/zmiany nazwy, aby zapobiec uszkodzeniom danych w przypadku awarii (skopiuj dane do nowego pliku pod nazwą tymczasową, a następnie zamień nazwy (atomicznie jeśli to możliwe), a następnie usuń stary plik) – derobert

3

<edycji>

Ach, edytować swój post, którego używasz C. Gdy otworzysz plik, otwórz go w trybie "w +", tak jak to, a zostanie on przycięty i gotowy do zapisu:

FILE* f = fopen("C:\\gabehabe.txt", "w+"); 
fclose(file); 

</edit >

Aby obciąć pliku w C++, można po prostu utworzyć obiekt ofstream do pliku, używając ios_base :: trunc jako tryb plik, aby go skrócić, tak:

ofstream x("C:\\gabehabe.txt", ios_base::trunc); 
+0

fopen skróci zawartość pliku "gabehabe.txt" i wskaże wskaźnik pliku na początku, prawda? Ale czy opróżni zawartość pliku przed zmianą położenia wskaźnika pliku? – Arpith

58

Jeśli chcesz zachować poprzednią zawartość pliku do pewnej długości (długość większa niż zero, które inne odpowiedzi zapewniają), a następnie P OSIX zapewnia funkcje truncate() i ftruncate() dla zadania.

#include <unistd.h> 
int ftruncate(int fildes, off_t length); 
int truncate(const char *path, off_t length); 

Nazwa wskazuje główny cel - skrócenie pliku. Ale jeśli określona długość jest dłuższa niż poprzednia długość, plik powiększa się (zero padding) do nowego rozmiaru. Zauważ, że ftruncate() działa na deskryptorze pliku, a nie na FILE *; można użyć:

if (ftruncate(fileno(fp), new_length) != 0) ...error handling... 

Należy jednak mieć świadomość, że mieszanie strumienia pliku (FILE *) i deskryptor pliku (int) dostępu do pojedynczego pliku jest w stanie doprowadzić do nieporozumień - patrz komentarze do niektórych kwestii . To powinno być ostatecznością.

Jest jednak prawdopodobne, że dla twoich potrzeb, skrócenie na otwartej przestrzeni jest wszystkim, czego potrzebujesz, a do tego opcje podane przez innych będą wystarczające.

+0

Dwie minuty do przodu ... fajnie! –

+0

Niezwykle podobne, Lance! Przynajmniej jedno z nas prawdopodobnie dostało poprawne informacje. (Używanie nie powinno być konieczne w nowszych standardach POSIX, jednak dla bezpieczeństwa nie stanowi ono żadnej szkody.) –

+1

Czy istnieje taka funkcja w C++ vs 2003 Nie mogłem jej znaleźć? brak załączników pomógł może coś przegapiłem? Nie chcę otwierać pliku za pomocą w, ale używaj pliku opanned już – sofr

5

Jeśli jest to uruchomić pod jakimś smaku UNIX API te powinny być dostępne:

#include <unistd.h> 
    #include <sys/types.h> 

    int truncate(const char *path, off_t length); 
    int ftruncate(int fd, off_t length); 

Według „człowieka skróconej” na moim Linuksie, są zgodne z POSIX. Pamiętaj, że te połączenia rzeczywiście zwiększą rozmiar pliku (!), Jeśli przekroczysz długość większą niż aktualna długość.