Вот решение, написанное на C для Windows. Он выполнит и закончит на 700 000 строк, 245 МБ файла в мгновение ока. (0.14 секунд)
В принципе, я храню карту памяти, чтобы получить доступ к содержимому с помощью функций, используемых для доступа к необработанной памяти. Как только файл был сопоставлен, я просто использую функцию strchr, чтобы найти местоположение одной из пары символов, используемых для обозначения EOL в окнах (\ n и \ r) - это говорит нам, как долго в байтах первая строка ,
Отсюда я просто memcpy от первого байта f второй строки до начала области отображения памяти (в основном, первый байт в файле).
После этого файл не отображается, дескриптор файла mem-mapped закрыт, и затем мы используем функцию SetEndOfFile, чтобы уменьшить длину файла по длине первой строки. Когда мы закрываем файл, он уменьшился на эту длину, и первая строка исчезла.
Имея файл уже в памяти, так как я только что создал и написал, он, очевидно, немного меняет время выполнения, но механизм кэширования окон является «виновником» здесь - тем же самым механизмом, который мы используем для создания работа завершена очень быстро.
Данные испытаний являются источником программы, дублированной 100 000 раз и сохраняются как testInput2.txt (вставьте его 10 раз, выберите все, скопируйте, вставьте 10 раз - замените оригинал 10, в общей сложности 100 раз - повторите до выхода достаточно большой.Я остановился здесь, потому что больше, похоже, делало Notepad ++ «бит» недовольным)
Ошибка проверки в этой программе практически не существует, и ожидается, что вход не будет UNICODE, т. Е. Вход 1 байт на символ. Последовательность EOL является 0x0D, 0x0A (\ г \ п)
Код:
#include <stdio.h>
#include <windows.h>
void testFunc(const char inputFilename[])
{
int lineLength;
HANDLE fileHandle = CreateFile(
inputFilename,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
NULL
);
if (fileHandle != INVALID_HANDLE_VALUE)
{
printf("File opened okay\n");
DWORD fileSizeHi, fileSizeLo = GetFileSize(fileHandle, &fileSizeHi);
HANDLE memMappedHandle = CreateFileMapping(
fileHandle,
NULL,
PAGE_READWRITE | SEC_COMMIT,
0,
0,
NULL
);
if (memMappedHandle)
{
printf("File mapping success\n");
LPVOID memPtr = MapViewOfFile(
memMappedHandle,
FILE_MAP_ALL_ACCESS,
0,
0,
0
);
if (memPtr != NULL)
{
printf("view of file successfully created");
printf("File size is: 0x%04X%04X\n", fileSizeHi, fileSizeLo);
LPVOID eolPos = strchr((char*)memPtr, '\r'); // windows EOL sequence is \r\n
lineLength = (char*)eolPos-(char*)memPtr;
printf("Length of first line is: %ld\n", lineLength);
memcpy(memPtr, eolPos+2, fileSizeLo-lineLength);
UnmapViewOfFile(memPtr);
}
CloseHandle(memMappedHandle);
}
SetFilePointer(fileHandle, -(lineLength+2), 0, FILE_END);
SetEndOfFile(fileHandle);
CloseHandle(fileHandle);
}
}
int main()
{
const char inputFilename[] = "testInput2.txt";
testFunc(inputFilename);
return 0;
}
Файлы просто не работают таким образом (по аналогии с сырой массив, вы не можете удалить первый элемент, не перемещая все остальные элементы на один слот). – crashmstr
Каждая ветвь этого оператора 'if' имеет' file.close(); lock.unlock(); '. Деструктор объекта 'std :: file' закроет файл, поэтому вам не нужно явно закрывать его (и когда' file.is_open() 'возвращает false, нет необходимости его закрывать). И, несомненно, для Boost для управления этим замком существует тип RAII с деструктором, чтобы разблокировать его. –
Да, конечно, «все» ... https://www.google.com/search?q=c%2B%2B+modify+file+in+place –