Вставка у удаление из файла
От: Syleiman  
Дата: 16.05.01 14:02
Оценка:
Есть файл произвольного размера. Надо быстро вставить в его произвольное место данные произвольной длинны. Аналогично и с удалением. У кого есть алгоритмы? Киньте, а?

Александр.
Re: Вставка у удаление из файла
От: Odissey Россия http://malgarr.blogspot.com/
Дата: 17.05.01 03:30
Оценка:
Здравствуйте Syleiman, вы писали:

S>Есть файл произвольного размера. Надо быстро вставить в его произвольное место данные произвольной длинны. Аналогично и с удалением. У кого есть алгоритмы? Киньте, а?


Делал я удаление куска из начала файла. Общий алгоритм такой —

— отображаем в память (MapViewOfFile)
— двигаем, удаляем (memmove и т.д.)
— снимаем отображение (UnmapViewOfFile)
— устанавливаем новый конец файла

или надо кусок кода?
Re[2]: Вставка у удаление из файла
От: Syleiman  
Дата: 17.05.01 10:25
Оценка:
Здравствуйте Odissey, вы писали:

O>Делал я удаление куска из начала файла. Общий алгоритм такой...


O>...или надо кусок кода?

Да, если Вас это не сильно затруднит.
Re[3]: Вставка у удаление из файла
От: Odissey Россия http://malgarr.blogspot.com/
Дата: 17.05.01 11:00
Оценка: 6 (1)
Здравствуйте Syleiman, вы писали:

S>Здравствуйте Odissey, вы писали:


O>>Делал я удаление куска из начала файла. Общий алгоритм такой...


O>>...или надо кусок кода?

S>Да, если Вас это не сильно затруднит.

примерчик выкусывания куска из начала файла:


void CBlaBlaBlaDlg::TruncateFromBegin(DWORD pos) 
{
    TRACE("Удалить с начала до %ld\n", pos);
    
    HANDLE hFile = CreateFile(m_sFileName, GENERIC_READ | GENERIC_WRITE,
        0,  NULL, OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL,  NULL);
    
    if (hFile == INVALID_HANDLE_VALUE)
    {
        m_sTmp.Format("Не могу открыть файл %s\n"
            "Ошибка: %ld", m_sFileName, GetLastError());
        MessageBox(m_sTmp, "Удаление записей", MB_OK | MB_ICONERROR);
        return;
    }
    
    DWORD dwFileSize = CFileMsg::GetSize(m_sFileName);
    TRACE("Размер до укорочения = %ld\n", dwFileSize);
    
    HANDLE hFileMap = CreateFileMapping(hFile, 
        NULL, PAGE_READWRITE,
        0, dwFileSize , NULL);
    
    if (hFileMap == NULL) 
    {
        // File-Mapping open failed.
        MessageBox("File map could not be opened", "Удаление записей", MB_OK | MB_ICONERROR);
        return;
    }
    
    LPVOID lpvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
    
    if (!lpvFile) 
    {
        MessageBox("Could not map view of file", "Удаление записей", MB_OK | MB_ICONERROR);
        return;
    }
    
    LPVOID lpvOffseet = (PVOID)((DWORD)(lpvFile) + pos);
    
    DWORD newsize = dwFileSize - pos;
    
    //        куда,   откуда,   сколько
    memmove(lpvFile, lpvOffseet, newsize);
    
    UnmapViewOfFile(lpvFile);
    CloseHandle(hFileMap);
    
    //переводим указатель
    DWORD result = SetFilePointer(hFile, newsize, 0, FILE_BEGIN);
    
    if (result != newsize)
    {
        m_sTmp.Format("Указатель не может быть смещен на %ld байт", newsize);
        MessageBox(m_sTmp, "Удаление записей", MB_OK | MB_ICONERROR);
        return;
    }
    
    //устанавливаем новый конец файла
    if (!SetEndOfFile(hFile))
    {
        m_sTmp.Format("Не могу установить новый конец файла %s\n"
            "Ошибка: %ld", m_sFileName, GetLastError());
        MessageBox(m_sTmp, "Удаление записей", MB_OK | MB_ICONERROR);
        return;
    }
    
    CloseHandle(hFile);
    
    TRACE("Новый размер %ld\n", CFileMsg::GetSize(m_sFileName));
    
    return;
}


примерно так
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.