문제

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

도움이 되었습니까?

해결책

플랫폼에 따라이를 수행하는 방법에는 여러 가지가 있습니다. 다음 선택 중에서 선택할 것입니다.

크로스 플랫폼

Trolltech의 QT에는 호출되는 객체가 있습니다 QFILESYSTEMWATCHER 파일 및 디렉토리를 모니터링 할 수 있습니다. 나는 당신에게 이런 종류의 기능을 제공하는 다른 크로스 플랫폼 프레임 워크가 있다고 확신하지만, 이것은 내 경험에서 상당히 잘 작동합니다.

Windows (Win32)

Win32 API 호출이 있습니다 findfirstchangenotification 일하는 일. API에 대한 작은 래퍼 클래스가 불리는 멋진 기사가 있습니다. 지정된 디렉토리에서 변경이 발생하는 경우 알림을받는 방법 당신을 시작할 것입니다.

Windows (.NET Framework)

.NET 프레임 워크와 함께 C ++/CLI를 사용하는 경우System.io.filesystemwatcher 당신의 선택 계급입니다. Microsoft에는 좋은 기사가 있습니다파일 시스템 변경을 모니터링하는 방법 이 수업을 사용합니다.

OS x

그만큼 fsevents API는 OS X 10.5에 새롭고 매우 완전한 기능을 갖추고 있습니다.

리눅스

사용 Inotify Alex는 그의 대답에서 언급했듯이.

다른 팁

플랫폼 독립적 일 필요가 없다면 "폴링"(주기적으로 확인)보다 기계로드가 적을 수있는 Linux의 접근 방식은 다음과 같습니다. inotify, 보다 http://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 );
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top