0

フォルダーの変更を監視し、追加されたファイル名を通知しようとしているので、ここに私のコードがあります

bool FileWatcher::NotifyChange()
{
    // Read the asynchronous result of the previous call to ReadDirectory
    DWORD dwNumberbytes;
    GetOverlappedResult(hDir, &overl, &dwNumberbytes, FALSE);

    // Browse the list of FILE_NOTIFY_INFORMATION entries

    FILE_NOTIFY_INFORMATION *pFileNotify = (FILE_NOTIFY_INFORMATION *)buffer[curBuffer];
    // Switch the 2 buffers
    curBuffer = (curBuffer + 1) % (sizeof(buffer)/(sizeof(buffer[0])));
    SecureZeroMemory(buffer[curBuffer], sizeof(buffer[curBuffer]));
    // start a new asynchronous call to ReadDirectory in the alternate buffer
    ReadDirectoryChangesW(
         hDir, /* handle to directory */
         &buffer[curBuffer], /* read results buffer */
         sizeof(buffer[curBuffer]), /* length of buffer */
         FALSE, /* monitoring option */
         FILE_NOTIFY_CHANGE_FILE_NAME  ,
         //FILE_NOTIFY_CHANGE_LAST_WRITE, /* filter conditions */
         NULL, /* bytes returned */
         &overl, /* overlapped buffer */
         NULL); /* completion routine */    

    for (;;) {
         (pFileNotify->Action == FILE_ACTION_ADDED)
        {
                qDebug()<<"in NotifyChange if ";
                char szAction[42];
                char szFilename[MAX_PATH] ;
                memset(szFilename,'\0',sizeof( szFilename));
                strcpy(szAction,"added");
                wcstombs( szFilename, pFileNotify->FileName, MAX_PATH);
                qDebug()<<"pFileNotify->FileName : "<<QString::fromWCharArray(pFileNotify->FileName)<<"\nszFilename : "<<QString(szFilename);                       

        }

        // step to the next entry if there is one
        if (!pFileNotify->NextEntryOffset)
            return false;
        pFileNotify = (FILE_NOTIFY_INFORMATION *)((PBYTE)pFileNotify + pFileNotify->NextEntryOffset);
    }
    pFileNotify=NULL;
    return true;
}

アラビア語の名前のファイルが追加されていない限り、正常に動作するので、取得します

pFileNotify->FileName :  "???  ???????.txt" 
szFilename :  ""  

UTF-8 コード ファイル名をサポートするにはどうすればよいですか ??? 任意のアイデアをください。

4

1 に答える 1

3

FILE_NOTIFY_INFORMATION::FileNamenull で終了していないことを除けば、何も問題はありません。

FileName: ディレクトリ ハンドルに関連するファイル名を含む可変長フィールド。ファイル名は Unicode 文字形式であり、null で終了していません。ファイルに短い名前と長い名前の両方がある場合、関数はこれらの名前のいずれかを返しますが、どちらの名前かは指定されていません。

FileNameLength:レコードのファイル名部分のサイズ (バイト単位)。この値には、終端のヌル文字は含まれないことに注意してください。

FILE_NOTIFY_INFORMATION::FileNameLength / sizeof(WCHAR)FileName が指す wchars の文字列の長さを取得するために使用する必要があります。したがって、あなたの場合、適切な方法は次のようになります。

size_t cchFileNameLength = pFileNotify->FileNameLength / sizeof(WCHAR);
QString::fromWCharArray( pFileNotify->FileName, cchFileNameLength );

文字列が null で終了することを期待する関数 (wcstombs など) を使用する必要がある場合は、サイズの一時バッファーを割り当てて、FILE_NOTIFY_INFORMATION::FileNameLength + sizeof(WCHAR)自分で null で終了する必要があります。


空の szFilename と疑問符については、変換できない文字を含む UTF16 (NTFS) ファイル名を ANSI に変換した結果です。変換が不可能な場合、wcstombs はエラーを返し、QDebug は変換できない文字を に変換し?ます。

wcstombs は、マルチバイト文字に変換できないワイド文字を検出すると、size_t 型への -1 キャストを返し、errno を EILSEQ に設定します。

したがって、Unicode ファイル名をサポートする必要がある場合は、ファイル名を ANSI に変換せず、Unicode をサポートする関数で排他的に処理してください。

于 2012-11-07T12:30:54.677 に答える