Обработка модификации файла

  • Автор темы indrikozver
  • Дата начала
I

indrikozver

#1
Подскажите пожалуйста способ, покрасивее, обработки модификации файла. Такой чтобы можно было в приложение ввернуть на WinAPI.
 
T
#2
В смысле? Разных версий формата файла?
Укажи в начале файла код версии
 
I

indrikozver

#3
Задача немного изменилась. Ту я всетаки решил при помощи ReadDirectoryChangesW.
Немного подробнее о самой задаче:
в системе есть некий текстовый файл (в известном месте и который ну точно ни куда не денется, я проверял). Этот файл иногда может изменяться, а может и оставаться без изменения неделями. Так вот программа должна реагировать на изменения в этом вайле: копировать новую версию в указанное мною место. Собственно сейчас все так и работает. Но это не эфективно в том смысле, что если в нем добавится один символ, то тащить за собой остальные 500 КВ думаю нет смысла, так за пару часов активных изменений можно пару гигабайт сожрать нефиг делать. Как узнать что изменилось в файле? Думаю можно прочитать предыдущую и текущую версии файла в строку и выполнить поиск подстроки в строке или ее какнить вычесть. Только понятия не имею как это можно сделать. Что вы мне на это подскажете?
Да и еще, на мой взгляд не маловажная деталь: файл если и чистится, то чистится целиком.
 
I

indrikozver

#4
Вот вроде даже сделал то что хотел... Вот код может кому еще понадобится... Но на самом деле последняя просьба. Не моглибы вы мне подсказать куда за каждое изменение файла по 16 килобайт оперативки съедается?

Что делает прога: она смотрит за файлом текстовым файлом в указанной папке и если он изменяется сохраняет то, что было дописано в него и новую версияю самого файла


checkFile.h
[codebox]#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <fstream.h>
#include <string>
#include <vector>

#include "resource.h"

// for test by ICQ
#define MONITOR_FILE "474824718.txt"
#define FILE_CONTROL "C:\\Program Files\\QIP\\Users\\235281902\\History\\474824718.txt"
#define DIR_CONTROL "C:\\Program Files\\QIP\\Users\\235281902\\History\\"

#define BUF_SIZE 16384
#define WM_FILE_NEW WM_USER + 1000
#define MAX_FILE_NAME 13

void checkFile();
void getFileName();
void compaireFile();
void saveSource(std::vector <std::string>, std::string);
std::vector <std::string> readFile(std::string);
DWORD WINAPI ThreadProc(LPVOID);[/codebox]


checkFile.cpp
[codebox]#include "checkFile.h"

std::string outName ="log\\log";

void getFileName() {
std::string fileName = "log\\log";
ifstream fIn(fileName.c_str(), ios::nocreate);
int counter = 0;
int iBuf=0;
char buffer[4];

while(fIn) {

if(iBuf < 10)
wsprintf(buffer, "000%d", iBuf);
else if(iBuf < 100)
wsprintf(buffer, "00%d", iBuf);
else if(iBuf < 1000)
wsprintf(buffer, "0%d", iBuf);
else
wsprintf(buffer, "%d", iBuf);
outName = fileName + buffer;
fIn.close();
fIn.open(outName.c_str(), ios::nocreate);
counter++;
iBuf = counter;
}
}

void checkFile() {

std::string dirName=DIR_CONTROL;

HANDLE hDir = CreateFile(dirName.c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);

BYTE *pBuf = (BYTE*) GlobalAlloc(GPTR, BUF_SIZE);
DWORD br=0;

BOOL res = ReadDirectoryChangesW(hDir, pBuf, BUF_SIZE, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, &br, 0, NULL);

FILE_NOTIFY_INFORMATION* pInfo = (FILE_NOTIFY_INFORMATION*) pBuf;
do {
if (pInfo->Action == FILE_ACTION_MODIFIED) {
char lpFileName[MAX_FILE_NAME];
WideCharToMultiByte(CP_ACP, 0, pInfo->FileName, pInfo->FileNameLength/2, lpFileName, MAX_FILE_NAME, 0, 0);
lpFileName[pInfo->FileNameLength/2] = 0;
pInfo += pInfo->NextEntryOffset;

if (!strcmp(lpFileName, MONITOR_FILE)) {
compaireFile();
}
}
} while (pInfo->NextEntryOffset);

GlobalFree(&pBuf);
}


DWORD WINAPI ThreadProc(LPVOID lpParam) {
while(1) {
checkFile();
}
return 0;
}


void compaireFile() {
char readBuffer[1024];

std::vector <std::string> newContent;
std::vector <std::string> oldContent;
std::vector <std::string> compareContent;

int counter;

newContent = readFile(FILE_CONTROL);
oldContent = readFile("__old__");

if (oldContent.size() < newContent.size()) {
getFileName();
if((oldContent.size() > 0)) {
if (strcmp(oldContent[0].c_str(), newContent[0].c_str())) {
saveSource(newContent, outName);
}
else {
counter = 0;
while((oldContent.size() > counter) && !strcmp(oldContent[counter].c_str(), newContent[counter].c_str())) {
counter++;
}
for (counter; counter < newContent.size(); counter++) {
compareContent.push_back(newContent[counter]);
}
saveSource(compareContent, outName);
}
}
else saveSource(newContent, outName);
}
else if (newContent.size() > 0) {
saveSource(newContent, outName);
}
saveSource(newContent, "__old__");
}


void saveSource(std::vector <std::string> content, std::string fileName) {
ofstream fOut(fileName.c_str());
int i=0;

for (i=0; i < content.size(); i++) {
if(!strcmp(content.c_str(), "--------------------------------------<-") || !strcmp(content.c_str(), "-------------------------------------->-"))
fOut << endl << endl << content.c_str() << endl;
else
fOut << content.c_str() << " ";
}

fOut.close();
}

std::vector <std::string> readFile(std::string fileName) {
char readBuffer[1024];
std::vector <std::string> content;

ifstream fIn(fileName.c_str());
while(fIn >> readBuffer) {
content.push_back(readBuffer);
}
fIn.close();

return content;
}[/codebox]


main.cpp
[codebox]#include "checkFile.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
HWND hwnd;
MSG msg;
char szWinName[] = "checker"; // window name

WNDCLASSEX wndclass;

// window description
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, "checker.ico");
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szWinName;
wndclass.hIconSm = LoadIcon(NULL, "checker.ico");


if(!RegisterClassEx(&wndclass)) return FALSE; // register window class


// make a window
hwnd = CreateWindow (
szWinName, // class name
szWinName, // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL // creation parameters
);


// The window message's handler start
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}


return msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT imsg, WPARAM wparam, LPARAM lparam)
{
DWORD dwID = 0;
char lszThreadParam[3];
static HANDLE m_hThread;

switch (imsg)
{
case WM_CREATE:
m_hThread = CreateThread( NULL, 0, ThreadProc, &lszThreadParam, 0, &dwID);
return 0;

case WM_DESTROY:
CloseHandle(m_hThread);
m_hThread = NULL;
PostQuitMessage(0);
return 0;


case WM_QUIT:
delete m_hThread;
return 0;
}


return DefWindowProc(hwnd, imsg, wparam, lparam);
}
[/codebox]


По возможности и по желанию напишите, что еще былобы не плохо доработать.