Я бы наверное:
- создать новый файл.
- искать в старом файле.
- сделать буферизованное чтение / запись из старого файла в новый файл.
- переименуйте новый файл поверх старого.
Чтобы выполнить первые три шага (проверка ошибок пропущена, например, я не могу вспомнить, что делает seekg, если размер файла меньше 500 КБ):
#include <fstream>
std::ifstream ifs("logfile");
ifs.seekg(-500*1000, std::ios_base::end);
std::ofstream ofs("logfile.new");
ofs << ifs.rdbuf();
Тогда я думаю, что вы должны сделать что-то нестандартное, чтобы переименовать файл.
Очевидно, что для этого нужно 500 КБ свободного места на диске, поэтому, если вы усекаете файл журнала по той причине, что он только что заполнил диск, это нехорошо.
Я не уверен, почему поиск идет медленно, поэтому я могу что-то упустить. Я не ожидал бы, что время поиска зависит от размера файла. Что может зависеть от файла, так это то, что я не уверен, обрабатывают ли эти функции файлы размером более 2 ГБ в 32-разрядных системах.
Если само копирование медленное, то в зависимости от платформы вы можете ускорить его, используя больший буфер, так как это уменьшает количество системных вызовов и, возможно, что более важно, количество раз, которое дисковая головка должна искать между точкой чтения и точкой записи. Для этого:
const int bufsize = 64*1024; // or whatever
std::vector<char> buf(bufsize);
...
ifs.rdbuf()->pubsetbuf(&buf[0], bufsize);
Проверьте его с разными значениями и посмотрите. Вы также можете попробовать увеличить буфер для ofstream, я не уверен, будет ли это иметь значение.
Обратите внимание, что использование моего подхода к "живому" файлу регистрации является проблематичным. Например, если запись журнала добавляется между копией и переименованием, то вы теряете ее навсегда, и любые открытые дескрипторы файла, который вы пытаетесь заменить, могут вызвать проблемы (это приведет к сбою в Windows и в Linux. заменит файл, но старый все равно будет занимать место и все еще будет записан, пока дескриптор не будет закрыт).
Если усечение выполняется из того же потока, который выполняет всю запись в журнал, тогда нет проблем, и вы можете сделать это простым. В противном случае вам нужно будет использовать блокировку или другой подход.
Является ли это полностью надежным, зависит от платформы и файловой системы: перемещение и замена могут быть или не быть атомарной операцией, но обычно это не так, поэтому вам, возможно, придется переименовать старый файл, а затем переименовать новый файл, затем удалите старый и восстановите после ошибки, которая при запуске обнаруживает, есть ли переименованный старый файл, и, если это так, помещает его обратно и перезапускает усечение. STL не может помочь вам справиться с различиями в платформах, но есть boost :: filesystem.
Извините, здесь так много предостережений, но многое зависит от платформы. Если вы работаете на ПК, то я озадачен, почему копирование мизерных пол-мегабайт данных занимает какое-то время.