Допустим, вы генерируете данные. У вас есть старые данные, которые вы fread()
из файла, затем выполняете некоторую обработку данных, генерируете дополнительные данные и затем записываете их в новый файл. Будьте осторожны, чтобы не перезаписать старый файл, потому что вы знаете, что попытка создать новый файл может потерпеть неудачу, и вы хотели бы сохранить ваши старые данные в этом случае (некоторые данные лучше, чем никаких данных). После завершения всех fwrite()
с, что все успешно (потому что вы тщательно проверили возвращаемое значение из fwrite()
), вы fclose()
файл. Затем вы rename()
только что написали файл и перезаписали старый файл.
Если fclose()
не удалось из-за ошибки записи (диск заполнен?), Вы просто перезаписали свой последний хороший файл чем-то, что могло быть нежелательным. К сожалению.
Итак, если это критично, вы должны проверить возвращаемое значение fclose()
.
В терминах кода:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *ifp = fopen("in.dat", "rb");
FILE *ofp = fopen("out.dat", "wb");
char buf[BUFSIZ];
size_t n;
int success = 1;
if (ifp == NULL) {
fprintf(stderr, "error opening in.dat\n");
perror("in.dat");
return EXIT_FAILURE;
}
if (ofp == NULL) {
fclose(ifp);
fprintf(stderr, "error opening out.dat\n");
perror("out.dat");
return EXIT_FAILURE;
}
while ((n = fread(buf, 1, sizeof buf, ifp)) > 0) {
size_t nw;
if ((nw = fwrite(buf, 1, n, ofp)) != n) {
fprintf(stderr, "error writing, wrote %lu bytes instead of %lu\n",
(unsigned long)n,
(unsigned long)nw);
fclose(ifp);
fclose(ofp);
return EXIT_FAILURE;
}
}
if (ferror(ifp)) {
fprintf(stderr, "ferror on ifp\n");
fclose(ofp);
fclose(ifp);
return EXIT_FAILURE;
}
#ifdef MAYLOSE_DATA
fclose(ofp);
fclose(ifp);
rename("out.dat", "in.dat"); /* Oops, may lose data */
#else
if (fclose(ofp) == EOF) {
perror("out.dat");
success = 0;
}
if (fclose(ifp) == EOF) {
perror("in.dat");
success = 0;
}
if (success) {
rename("out.dat", "in.dat"); /* Good */
}
#endif
return EXIT_SUCCESS;
}
В приведенном выше коде мы были осторожны с fopen()
, fwrite()
и fread()
, но даже в этом случае не проверка fclose()
может привести к потере данных (при компиляции с определением MAYLOSE_DATA
).