C++:监视文件大小。这会不会有问题?
C++: Monitor file size. Can this be problematic?
我正在编写一个 GUI 程序,用于将文件夹中的文件与服务器同步。我所知道的关于这些文件的信息是它们总是被写入而不是被删除。我担心的是在写入文件时开始上传文件。所以为了避免这种情况,我发明了一种解决问题的方法,我需要一些专家告诉我这是不是错误的。
所以我所做的是我有一个带计时器的事件循环。每次此计时器滴答作响时,它都会查看是否添加了新文件。如果找到新文件,我使用这个简单的函数来获取文件大小:
std::size_t GetFileSize(const std::string &filename)
{
std::ifstream file(filename.c_str(), std::ios::binary | std::ios::ate);
return file.tellg();
}
然后,我将新文件名、大小存储在表单的数据结构中(忽略 std::
以使其视觉友好,因为下一行要写 5 个):
deque<pair<string, pair<size_t, long> > fileMonitor;
(如果可能,请建议更好的数据结构。unordered_multimap
似乎做了类似的工作)。
所以这将存储文件名(在那个字符串中),它的大小(在那个 size_t 中)和文件大小被检查的次数没有改变,我们称之为 checks
。所以每次计时器滴答作响时,我都会寻找新文件,并检查 fileMonitor
中文件的大小是否发生了变化。对于单个文件,如果文件大小与之前不同,则checks = 1
,如果文件大小相同,则checks++
。
现在在每次迭代中,我检查计时器的interval*checks > timeout
,然后文件已经足够长的时间没有更改,我可以判断文件是稳定的并且没有被更新。
明显的问题:为什么我不使用像 inotify
这样的东西?因为我需要跨平台且结构简单的东西,因为我已经知道我要上传的文件的行为。不幸的是,boost 没有为此提供解决方案,所以我不得不自己发明。
您可以访问写作程序吗?在这种情况下,我建议先将数据写入一个临时文件,并在写入完成后才重命名它(类似于文件系统上的 atomic
操作)。否则你的 "wait an appropriately long time for a change" 方法总是有可能失败,因为你无法判断编写程序长时间不更改文件的原因可能是什么。
- 添加 HD5 格式:
文件甚至可以在不改变大小的情况下改变内容但是:
来自https://www.hdfgroup.org/HDF5/doc/H5.format.html#FileMetaData
File Consistency Flags
This value contains flags to indicate information about the
consistency of the information contained within the file. Currently,
the following bit flags are defined:
Bit 0 set indicates that the file is opened for write-access.
Bit 1 set indicates that the file has been verified for consistency and is guaranteed to be consistent with the format defined
in this document.
Bits 2-31 are reserved for future use.
Bit 0 should be set as the first action when a file is opened for
write access and should be cleared only as the final action when
closing a file. Bit 1 should be cleared during normal access to a file
and only set after the file's consistency is guaranteed by the library
or a consistency utility.
我假设 hd5 API 提供了 独占 打开这些文件的方法,除了您的轮询方法外,我还会尝试它。
我正在编写一个 GUI 程序,用于将文件夹中的文件与服务器同步。我所知道的关于这些文件的信息是它们总是被写入而不是被删除。我担心的是在写入文件时开始上传文件。所以为了避免这种情况,我发明了一种解决问题的方法,我需要一些专家告诉我这是不是错误的。
所以我所做的是我有一个带计时器的事件循环。每次此计时器滴答作响时,它都会查看是否添加了新文件。如果找到新文件,我使用这个简单的函数来获取文件大小:
std::size_t GetFileSize(const std::string &filename)
{
std::ifstream file(filename.c_str(), std::ios::binary | std::ios::ate);
return file.tellg();
}
然后,我将新文件名、大小存储在表单的数据结构中(忽略 std::
以使其视觉友好,因为下一行要写 5 个):
deque<pair<string, pair<size_t, long> > fileMonitor;
(如果可能,请建议更好的数据结构。unordered_multimap
似乎做了类似的工作)。
所以这将存储文件名(在那个字符串中),它的大小(在那个 size_t 中)和文件大小被检查的次数没有改变,我们称之为 checks
。所以每次计时器滴答作响时,我都会寻找新文件,并检查 fileMonitor
中文件的大小是否发生了变化。对于单个文件,如果文件大小与之前不同,则checks = 1
,如果文件大小相同,则checks++
。
现在在每次迭代中,我检查计时器的interval*checks > timeout
,然后文件已经足够长的时间没有更改,我可以判断文件是稳定的并且没有被更新。
明显的问题:为什么我不使用像 inotify
这样的东西?因为我需要跨平台且结构简单的东西,因为我已经知道我要上传的文件的行为。不幸的是,boost 没有为此提供解决方案,所以我不得不自己发明。
您可以访问写作程序吗?在这种情况下,我建议先将数据写入一个临时文件,并在写入完成后才重命名它(类似于文件系统上的 atomic
操作)。否则你的 "wait an appropriately long time for a change" 方法总是有可能失败,因为你无法判断编写程序长时间不更改文件的原因可能是什么。
- 添加 HD5 格式:
文件甚至可以在不改变大小的情况下改变内容但是:
来自https://www.hdfgroup.org/HDF5/doc/H5.format.html#FileMetaData
File Consistency Flags
This value contains flags to indicate information about the consistency of the information contained within the file. Currently, the following bit flags are defined:
Bit 0 set indicates that the file is opened for write-access. Bit 1 set indicates that the file has been verified for consistency and is guaranteed to be consistent with the format defined
in this document. Bits 2-31 are reserved for future use.
Bit 0 should be set as the first action when a file is opened for write access and should be cleared only as the final action when closing a file. Bit 1 should be cleared during normal access to a file and only set after the file's consistency is guaranteed by the library or a consistency utility.
我假设 hd5 API 提供了 独占 打开这些文件的方法,除了您的轮询方法外,我还会尝试它。