- 締切済み
ReadDirectoryChangesWで取得した変更ファイル名について
質問させて頂きます。 現在、非同期で指定したディレクトリを監視するプログラムを組んで降りますが 監視しているディレクトリ内のファイルが削除/変更された場合に 通知されたファイル名の終端に結構な頻度で余計な文字が混ざっています 例えば"test.txt"というファイル名が通知されるはずが"test.txt↑"といったファイル名になります その為、unicodeからANSIに文字列を変換する際、余計な文字まで変換され 現在困っています ReadDirectoryChangesWを呼ぶ前に、バッファはきちんとZeroMemoryしております。 処理しているコードの一部です ZeroMemory( szBuffer, sizeof(szBuffer) ); ReadDirectoryChangesW( hDirectory, szBuffer, sizeof(szBuffer), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME, &dwResult, &ol, NULL ); /* ここに待機処理が入り、下記は変更通知を受けた場合の処理です */ iIndex = 0; GetOverlappedResult( hDirectory, &ol, &dwResult, TRUE ); for( ; ; ) { pNotify = (FILE_NOTIFY_INFORMATION *)&szBuffer[iIndex]; if( !pNotifi->NextEntryOffset ) { iIndex += pNotifyInfo->NextEntryOffset; } else { break; } } 上記コードが現在のコードを一部記載した物です。 何故、余計な文字が混入されるのでしょうか? ご教授の程、よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- prophetok
- ベストアンサー率44% (13/29)
すいません私がが馬鹿でした。 配列の添え字間違えていますね。 ただ、下記は気をつけてください。 直接szBufferに値を代入すると、NextEntryOffsetの値を壊して、うまく動作しなくなるおそれがありますよ。
- prophetok
- ベストアンサー率44% (13/29)
#3の補正 >> 1 は >> 1 + 1 の間違い? でした。 下記呼んでくださいね。#2参照 FileNameLength The size of the file name portion of the record, in bytes. Note that this value does not include the terminating null character.
- prophetok
- ベストアンサー率44% (13/29)
#1のお礼 pNotifi->FileName[ pNotifi->FileNameLength >> 1 ] = '\0'; >> 1 は + 1 の間違い? 直接szBufferに値を代入すると、NextEntryOffsetの値を壊して、うまく動作しなくなるおそれがありますよ。 お節介ながら、ちょっと心配になりましたので。
- prophetok
- ベストアンサー率44% (13/29)
#1の補足 #1の点は理解できていて、ファイル名を格納するバッファにNULLを代入する際の位置が間違えているのかもしれませんね。 肝心のファイル名を評価する部分が記述されていないのですが、正しい位置にNULLを代入していますか? FileNameLength はバイト数なので、下記のようにする必要があります。 LPWSTR buf = new WCHAR[pNotifyInfo->FileNameLength / sizeof(WCHAR) + 1]; memcpy(buf,pNotifyInfo->FileName, pNotifyInfo->FileNameLength ); buf[pNotifyInfo->FileNameLength / sizeof(WCHAR) + 1] = NULL;
- prophetok
- ベストアンサー率44% (13/29)
構造体の解説をよく読みましょう。 最後の、 is not null-terminated が肝心なところです。 typedef struct _FILE_NOTIFY_INFORMATION { DWORD NextEntryOffset; DWORD Action; DWORD FileNameLength; WCHAR FileName[1]; }FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION; FileNameLength The size of the file name portion of the record, in bytes. Note that this value does not include the terminating null character. FileName A variable-length field that contains the file name relative to the directory handle. The file name is in the Unicode character format and is not null-terminated.
お礼
有難うございます。 >is not null-terminated 通知されたファイル名に終端は入らないのですね… すぐにunicodeからANSIに変換する処理を行っておりましたので pNotifi->FileName[ pNotifi->FileNameLength >> 1 ] = '\0'; とすることで、無事解決しました。 本当に有難うございました。