gpt4 book ai didi

c++ - 在 Windows 7 中观察文件的变化

转载 作者:可可西里 更新时间:2023-11-01 10:08:12 26 4
gpt4 key购买 nike

我有一个适用于 Windows 7 的 Visual Studio 2008 C++ 应用程序,我想在其中监视文件的更改。

文件可以这样修改:

std::ofstream myfile_;

void LogData( const char* data )
{
myfile_ << data << std::endl;
// note that the file output buffer is flushed by std::endl, but the file is not closed.
}

我尝试使用 ReadDirectoryChangesW 和 FindFirstChangeNotification 和 FILE_NOTIFY_CHANGE_SIZE | 来观察文件的目录 | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_FILE_NAME 标志。但是,在文件句柄实际关闭之前,这些 API 都不会检测到文件更改。

有什么方法可以在文件实际写入时但在文件句柄关闭之前检测到更改?

谢谢,保罗H


更新根据@Edwin 的建议,我正在尝试使用 Journal 功能。但是,我有几个问题。

  1. FSCTL_READ_USN_JOURNAL 立即返回。它不会阻塞。 (不过,这可能与问题 2 有关)
  2. 无论我的句柄指向何处(我尝试打开目录“C:\Foo\Bar”和文件“C:\Foo\Bar\MyFile.txt”的句柄)我似乎得到任何对 C: 卷所做的更改。有没有办法限制 FSCTL_READ_USN_JOURNAL 给我的内容?

为简洁起见省略了错误检查。

boost::shared_ptr< void > directory( 
::CreateFileW( L"C:\\Foo\\Bar\\Myfile.txt",
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ),
::CloseHandle );

USN_JOURNAL_DATA journal = { 0 };
DWORD returned = 0;
::DeviceIoControl( directory.get(), FSCTL_QUERY_USN_JOURNAL, NULL, 0, &journal, sizeof( journal ), &returned, NULL );

BYTE buffer[ 4096 ] = { 0 };
READ_USN_JOURNAL_DATA read = { 0, USN_REASON_DATA_EXTEND | USN_REASON_DATA_TRUNCATION, FALSE, 0, 0, journal.UsnJournalID };
::DeviceIoControl( directory.get(), FSCTL_READ_USN_JOURNAL, &read, sizeof( read ), &buffer, sizeof( buffer ), &returned, NULL );

for( USN_RECORD* record = ( USN_RECORD* )( buffer + sizeof( USN ) );
( ( BYTE* )record - buffer ) < returned;
record = ( USN_RECORD* )( ( BYTE* )record + record->RecordLength ) )
{
ATLTRACE( L"%s\r\n", record->FileName );
}

示例输出(这些都不在 C:\Foo\Bar 目录中):

AeXProcessList.txt`
AeXProcessList.txt`
AeXAMInventory.txt`
AeXAMInventory.txt`
AeXProcessList.txt`
AeXProcessList.txtP
access.log`
mysqlgeneral.log
E804.tmp
apache_error.log
E804.tmp
CHROME.EXE-5FE9909D.pfh
CHROME.EXE-5FE9909D.pfp
SyncData.sqlite3-journal
CHROME.EXE-5FE9909D.pfh
CHROME.EXE-5FE9909D.pfP
1211.tmp
SyncData.sqlite3-journal
AeXAMInventory.txt

最佳答案

你可以使用

Change Journal Operations

(参见 MSDN 文档)

这是检测文件系统中任何更改的唯一 100% 保证方法。但它非常复杂。

关于c++ - 在 Windows 7 中观察文件的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9279456/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com