Как очистить бинарный файл с

Обновлено: 02.07.2024

При записи информации в двоичный файл символы и числа записываются в виде последовательности байт.

Для того чтобы записать данные в двоичный файл, необходимо:

  1. описать файловую переменную типа FAIL * с помощью оператора FILE *filename, здесь filename — имя переменной, где будет храниться указатель на файл.
  2. открыть файл с помощью функции fopen
  3. записать информацию в файл с помощью функции fwrite
  4. закрыть файл с помощью функции fclose

Для того чтобы считать данные из двоичного файла, необходимо:

  1. описать переменную типа FILE *
  2. открыть файл с помощью функции fopen
  3. считать необходимую информацию из файла с помощью функции fread, при этом следить за тем достигнут ли конец файла.
  4. закрыть файл с помощью функции fclose

Рассмотрим основные функции, необходимые для работы с двоичными файлами.

Для открытия файла предназначена функция fopen.

FILE *fopen(const *filename, const char *mode)

Здесь filename — строка, в которой хранится полное имя открываемого файла, mode — строка, определяющая режим работы с файлом; возможны следующие значения:

  • «rb» — открываем двоичный файл в режиме чтения;
  • «wb» — создаем двоичный файл для записи; если он существует, то его содержимое очищается;
  • «ab» — создаем или открываем двоичный файл для дозаписи в конец файла;
  • «rb+» — открываем существующий двоичный файл в режиме чтения и записи;
  • «wb+» — открываем двоичный файл в режиме чтения и записи, существующий файл очищается;
  • «ab+» — двоичный файл открывается или создается для исправления существующий информации и добавления новой в конец файла.

Функция возвращает в файловой переменной f значение NULL в случае неудачного открытия файла. После открытия файла доступен 0-й его байт, указатель файла равен 0, значение которого по мере чтения или записи смещается на считанное (записанное) количество байт. Текущие значение указателя файла — номер байта, начиная с которого будет происходить операция чтения или записи.

Для закрытия файла предназначена функция fclose:

int fclose(FILE *filename);

Она возвращает 0 при успешном закрытие файла и EOF в противном случае.

Функция remove предназначена для удаления файлов:

int remove(const char *filename);

Эта функция удаляет с диска файл с именем filenema. Удаляемый файл должен быть закрыт. Функция возвращает ненулевое значение, если файл не удалось удалить.

Для переименования файлов предназначена функция rename:

int rename(const char *oldfilename, const char *newfilename);

Первый параметр — старое имя файла, второй — новое. Возвращает 0 при удачном завершении программы.

Чтение из двоичного файла осуществляется с помощью функции fread:

fread(void *ptr, size, n, FILE *filename);

Функция fread считывает из файла filename в массив ptr n элементов размера size. Функция возвращает количество считанных элементов. После чтения из файла его указатель смещается на n*size байт.

Запись в двоичный файл осуществляется с помощью функции fwrite:

fwrite(const void *ptr, size, n, FILE *filename);

Функция fwrite записывает в файл filename из массива ptr n элементов размера size. Функция возвращает количество записанных элементов. После записи информации в файл указатель смещается на n*size байт.

Для контроля достижения конца файла есть функция feof:

int feof(FILE *filename);

Она возвращает ненулевое значение если достигнут конец файла.

Для более точного усвоения материала предлагаю рассмотреть пару стандартных задач.

Задача 1

Создать двоичный файл D:\\game\\noobs.dat и записать в него целое число n и n вещественных чисел.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Задача 2

Вывести на экран содержимого созданного в прошлой задаче двоичного файла D:\\game\\noobs.dat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Двоичный файл — последовательная структура данных, после открытия файла доступен первый байт, хранящийся в нем. Можно последовательно записывать или считывать данные из файла. Допустим, необходимо считать пятнадцатое число, а затем первое. С помощью последовательного доступа это можно сделать следующим способом:

Как видно, такое чтение чисел из файла, а затем повторное открытие файла — не самый удобный способ. Гораздо удобнее будет использовать функцию fseek перемещения указателя файла к заданному байту.

int fseek(FILE *filename, long int offset, int origin);

Функция устанавливает указатель текущий позиции файла F в соответствии со значением начала отсчета origin и смещения offset. Параметр offset равен количеству байтов, на которые будет смещен указатель файла относительно начала отсчета, заданного параметром origin. В качестве значения для параметра origin должно быть взято одно из следующих значений отсчета смещения offset, определенных в заголовке stdio.h:

  • SEEK_SET — с начала файла;
  • SEEK_CUR — с текущей позиции;
  • SEEK_END — с конца файла.

Функция возвращает нулевое значение при успешном выполнение операции, ненулевое — при возникновении сбоя при выполнении смещения

Функция fseek фактически реализует прямой доступ к любому значению в файле. Необходимо только знать месторасположение (номер байта) значения в файле. Рассмотрим использование прямого доступа в двоичных файлах на примере решения следующей задачи.

Задача 3

В созданном раннее двоичном файле D:\\game\\noobs.dat, поменять местами наибольшее и наименьшее из вещественных чисел.

Алгоритм решения задачи состоит из следующих этапов:

  1. чтение вещественных из файла в массив a.
  2. поиск в массиве а максимального (max) и минимального (min) значения и их номеров (imax, imin).
  3. перемещения указателя файла к максимальному значению и запись min.
  4. перемещения указателя файла к минимальному значению и запись max.

Ниже приведен текст программы решения задачи с комментариями.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

Итак, мы рассмотрели основные принципы работы с файлами в C++. В следующих уроках они вам еще встретятся, поэтому усвойте их как можно лучше.

Репутация: нет
Всего: нет

Как удалять из него информацию? Через поиск ничего не нашёл.

Репутация: 11
Всего: 61

DFooz,
можно делать как минимум, двумя способами:

1. Скопировать из исхходного файла в файл-буфер все, что идет до удаляемого куска. Потом то же самое для куска после. Старый файл удалить. Новый переименовать и дать имя старого.

2 способ проходит только для чистого С

Возможно, я не прав, так что пусть меня поправят если что, но НЕТ стандартного метода для работы с потоками (файлами) в стиле С++, который позволил бы обрезать файл

Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей

Репутация: нет
Всего: нет

понятно.
в текстовых тоже только 2 этих способа работают?

Репутация: 11
Всего: 61

Цитата

в текстовых тоже только 2 этих способа работают?
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей

Репутация: 1
Всего: 39

хотелось бы понять по какому принципу удаляется инфа, тем не
менее если известен точный размер данных которые нужно оставить и удалить
то пользуйся fseek();

Репутация: 11
Всего: 61

Цитата

если известен точный размер данных которые нужно оставить и удалить
то пользуйся fseek();

К сожалению, fseek() только перемещает указатель файла в нужное место и всё. Данные файла можно будет только переписать поверх или записать дальше в конец файла. А само удаление - см. мой первый пост.
или вы что-то недоговорили

Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей

Репутация: нет
Всего: нет

Цитата

хотелось бы понять по какому принципу удаляется инфа

Репутация: 1
Всего: 39

наверно не договорил или не додумал имел ввиду что ездить по файлу удалять его, после чего собрать и перезаписать
похоже на твой вариант, есть еще мысль такая
допустим есть файл old.txt со следующим содержимым:
123456789qwertyuiopasdfghjklzxcvbnm
и мы знаем что символы которые надо удалить занимают позиции номер 10 11 12 13,
нам надо удалить qwer,
делаем так .

думаю с массивом работать с произвольным доступом проще чем с файлом

Репутация: 8
Всего: 146

я так понял , делается что то типа базы данных, и посоветую делать также как в DB в записи есть поле которое помечает что запись удалена,
а при архивации все записи помечаные как удаленые удаляются,
скорость работы повышается + появляется возможность откатится

Добавлено @ 22:48
codelord, а если файл в 100 мегабайт

Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности.

Репутация: 1
Всего: 39

т.е. всеравно не понял,
приведи кусочек файла.

Добавлено @ 22:50

ну наверно будет не быстро .
хотя тут надо уточнять и размер файла и потребности.

Репутация: 1
Всего: 39

п.с. на моем скромном компьютере приблизительно 10 мегов в сек.

Репутация: нет
Всего: нет

Цитата

т.е. всеравно не понял,smile
приведи кусочек файла.
Цитата

в DB в записи есть поле которое помечает что запись удалена

ЧТо такое DB? Как примерно пометить? В новый файл записать, что хочу удалить?

Репутация: 1
Всего: 39

извини может выразился не верно, я имел ввиду кусочек файла с которым надо работать,
т.е. из которого надо удалять.

Репутация: 8
Всего: 146


нет просто будешь находить в файле позицию и помечать как удаленную запись , а после всех действий или через время , допустим через неделю, будешь выкидывать все удаленые, для сохранения места на диске
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности.

Репутация: нет
Всего: нет

чего извиняться-то=)
что-то типа такого:
Петя диск 1 19.04.2006

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это! хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

[ Время генерации скрипта: 0.1449 ] [ Использовано запросов: 21 ] [ GZIP включён ]

Читайте также: