Усечение файла в с ++ - PullRequest
2 голосов
/ 29 апреля 2011

Я писал программу на C ++ и задаюсь вопросом, может ли кто-нибудь помочь мне с ситуацией, описанной здесь.

  1. Предположим, у меня есть файл журнала размером около 30 МБ, я скопировал последние 2 МБ файла в буфер программы.

  2. Я удаляю файл (или очищаю содержимое), а затем записываю обратно 2 МБ в файл.

Пока все работает нормально. Но проблема в том, что я читаю файл (последние 2 МБ) и очищаю файл (файл 30 МБ), а затем записываю обратно последние 2 МБ. В случае, если я копирую последние 300 МБ файла из файла объемом 1 ГБ, потребуется много времени.

У кого-нибудь есть идея сделать этот процесс проще?

При наличии большого файла журнала следует учитывать следующие причины.

Дисковое пространство: Файлы журнала представляют собой несжатый текст и занимают много места. Типичное сжатие уменьшает размер файла на 10: 1. Однако файл не может быть сжат когда он используется (заблокирован). Таким образом, файл журнала должен быть повернут из использования.

Системные ресурсы: Регулярное открытие и закрытие файла будет занимать много системы ресурсов и это снизит производительность сервера.

Размер файла: Небольшие файлы легче резервировать и восстанавливать в случае сбоя.

Я просто не хочу копировать, очищать и перезаписывать последние конкретные строки в файл. Просто более простой процесс ....: -)

РЕДАКТИРОВАТЬ: не делать никаких внутренних процессов для поддержки ротации журналов. logrotate - это инструмент.

Ответы [ 4 ]

5 голосов
/ 29 апреля 2011

Я бы предложил немного другой подход.

  1. Создать новый временный файл
  2. Скопировать необходимые данные из исходного файла во временный файл
  3. Закрытьоба файла
  4. Удалить исходный файл
  5. Переименовать временный файл с тем же именем, что и исходный файл

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

1 голос
/ 29 апреля 2011

Лучшим подходом может быть не позволить файлу расти настолько большим, а использовать вращающиеся файлы журнала с заданным максимальным размером на файл журнала и максимальным количеством сохраняемых старых файлов.

1 голос
/ 29 апреля 2011

Если это ваш файл ранее:

-----------------++++

Где - - это то, что вы не хотите, а + - это то, что вы хотите, самый портативный способ получить:

++++

... как ты и сказал.Прочитайте в нужном разделе (+), удалите / очистите файл (как в случае fopen(... 'wb') or something similar и запишите нужный бит (+).

Для выполнения более сложных задач требуется помощь, зависящая от ОС)и не является переносимым. К сожалению, я не верю, что в какой-либо крупной ОС есть поддержка того, что вы хотите. Может существовать поддержка «truncate после position X» (что-то вроде head), но не tail как операция, которую вы запрашиваете.

Такая операция будет трудна для реализации, так как различные размеры блоков в файловых системах (если файловая система имеет размер блока)Это может привести к проблемам. В лучшем случае вы будете ограничены сокращением границ блоков, но это будет Гарри. Это настолько редкий случай, что, вероятно, именно поэтому такая процедура не поддерживается напрямую.

0 голосов
/ 29 апреля 2011

Если вы можете контролировать процесс записи, то, что вы, вероятно, хотите здесь сделать, это записать в файл как кольцевой буфер . Таким образом, вы можете хранить последние X байтов данных, не выполняя то, что вы предлагаете.

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

...