Nice programing

내 프로그램이 C ++에서 파일 수정을 감시하게하려면 어떻게해야합니까?

nicepro 2020. 11. 17. 21:03
반응형

내 프로그램이 C ++에서 파일 수정을 감시하게하려면 어떻게해야합니까?


예를 들어 외부 프로그램이 파일을 수정하는시기를 감지하고 사용자가 원하는 경우 파일을 다시로드 할 수있는 Visual Studio와 같은 많은 프로그램이 있습니다. C ++에서 이런 종류의 작업을 수행하는 비교적 쉬운 방법이 있습니까 (반드시 플랫폼 독립적 일 필요는 없음)?


플랫폼에 따라 여러 가지 방법이 있습니다. 다음 중에서 선택합니다.

크로스 플랫폼

Trolltech의 Qt에는 파일과 디렉터리를 모니터링 할 수있는 QFileSystemWatcher 라는 개체 가 있습니다. 이런 종류의 기능을 제공하는 다른 크로스 플랫폼 프레임 워크도 있다고 확신하지만이 프레임 워크는 제 경험상 상당히 잘 작동합니다.

Windows (Win32)

작업을 수행하는 FindFirstChangeNotification 이라는 Win32 API가 있습니다 . API를위한 작은 래퍼 클래스가 How to get a notification if change is changed in a specified directory that will get you start라는 멋진 기사 가 있습니다.

Windows (.NET Framework)

.NET Framework에서 C ++ / CLI를 사용해도 괜찮다면 System.IO.FileSystemWatcher 를 선택하는 것이 좋습니다. Microsoft에는 이 클래스를 사용하여 파일 시스템 변경 사항을 모니터링하는 방법대한 멋진 기사가 있습니다.

OS X

FSEvents의 API는 OS X 10.5에 대한 새롭고 매우 완전한 기능을 갖춘입니다.

리눅스

Alex가 답변에서 언급했듯이 inotify사용하십시오 .


플랫폼에 독립적 일 필요가없는 경우 "폴링"(주기적으로 확인)보다 시스템 부하가 적을 수있는 Linux의 접근 방식 inotifyhttp://en.wikipedia.org/wiki/Inotify 및 예를 들어 많은 링크가 있습니다. Windows의 경우 http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx를 참조 하십시오 .


SimpleFileWatcher 가 당신이 찾고있는 것일 수 있습니다. 그러나 물론 그것은 외부 의존성입니다. 아마도 그것은 당신에게 선택권이 아닐 것입니다.


물론, VC ++처럼. 파일을 열 때 마지막으로 수정 된 시간을 가져 오며 파일이 열려있는 동안 주기적으로 확인합니다. last_mod_time> saved_mod_time이면 발생한 것입니다.


WinCE의 실례

void FileInfoHelper::WatchFileChanges( TCHAR *ptcFileBaseDir, TCHAR *ptcFileName ){
static int iCount = 0;
DWORD dwWaitStatus; 
HANDLE dwChangeHandles; 

if( ! ptcFileBaseDir || ! ptcFileName ) return;

wstring wszFileNameToWatch = ptcFileName;

dwChangeHandles = FindFirstChangeNotification(
    ptcFileBaseDir,
    FALSE,
    FILE_NOTIFY_CHANGE_FILE_NAME |
    FILE_NOTIFY_CHANGE_DIR_NAME |
    FILE_NOTIFY_CHANGE_ATTRIBUTES |
    FILE_NOTIFY_CHANGE_SIZE |
    FILE_NOTIFY_CHANGE_LAST_WRITE |
    FILE_NOTIFY_CHANGE_LAST_ACCESS |
    FILE_NOTIFY_CHANGE_CREATION |
    FILE_NOTIFY_CHANGE_SECURITY |
    FILE_NOTIFY_CHANGE_CEGETINFO
    );

if (dwChangeHandles == INVALID_HANDLE_VALUE) 
{
    printf("\n ERROR: FindFirstChangeNotification function failed [%d].\n", GetLastError());
    return;
}

while (TRUE) 
{ 
    // Wait for notification.
    printf("\n\n[%d] Waiting for notification...\n", iCount);
    iCount++;

    dwWaitStatus = WaitForSingleObject(dwChangeHandles, INFINITE); 
    switch (dwWaitStatus) 
    { 
        case WAIT_OBJECT_0: 

            printf( "Change detected\n" );

            DWORD iBytesReturned, iBytesAvaible;
            if( CeGetFileNotificationInfo( dwChangeHandles, 0, NULL, 0, &iBytesReturned, &iBytesAvaible) != 0 ) 
            {
                std::vector< BYTE > vecBuffer( iBytesAvaible );

                if( CeGetFileNotificationInfo( dwChangeHandles, 0, &vecBuffer.front(), vecBuffer.size(), &iBytesReturned, &iBytesAvaible) != 0 ) {
                    BYTE* p_bCurrent = &vecBuffer.front();
                    PFILE_NOTIFY_INFORMATION info = NULL;

                    do {
                        info = reinterpret_cast<PFILE_NOTIFY_INFORMATION>( p_bCurrent );
                        p_bCurrent += info->NextEntryOffset;

                        if( wszFileNameToWatch.compare( info->FileName ) == 0 )
                        {
                            wcout << "\n\t[" << info->FileName << "]: 0x" << ::hex << info->Action;

                            switch(info->Action) {
                                case FILE_ACTION_ADDED:
                                    break;
                                case FILE_ACTION_MODIFIED:
                                    break;
                                case FILE_ACTION_REMOVED:
                                    break;
                                case FILE_ACTION_RENAMED_NEW_NAME:
                                    break;
                                case FILE_ACTION_RENAMED_OLD_NAME:
                                    break;
                            }
                        }
                    }while (info->NextEntryOffset != 0);
                }
            }

            if ( FindNextChangeNotification( dwChangeHandles ) == FALSE )
            {
                printf("\n ERROR: FindNextChangeNotification function failed [%d].\n", GetLastError());
                return;
            }

            break; 

        case WAIT_TIMEOUT:
            printf("\nNo changes in the timeout period.\n");
            break;

        default: 
            printf("\n ERROR: Unhandled dwWaitStatus [%d].\n", GetLastError());
            return;
            break;
    }
}

FindCloseChangeNotification( dwChangeHandles );
}

Add an answer for libuv (though it's written in C), it has support for both Windows and Linux with system-specific APIs:

inotify on Linux, FSEvents on Darwin, kqueue on BSDs, ReadDirectoryChangesW on Windows, event ports on Solaris, unsupported on Cygwin

You may check the document here, beware that the document says that it's not very consistent.

참고URL : https://stackoverflow.com/questions/931093/how-do-i-make-my-program-watch-for-file-modification-in-c

반응형