【问题标题】:open and get exact size of existing memory mapped file on windows在 Windows 上打开并获取现有内存映射文件的确切大小
【发布时间】:2013-08-20 19:22:39
【问题描述】:

我们的服务日志文件之一映射到内存。我有另一个应用程序跟踪日志文件上的一些正则表达式,所以我需要定期获取日志文件大小并读取即将到来的行(如果有)。我通过 ftell() 检查日志文件大小以获取以字节为单位的大小,但是它返回 4mb,因为我猜它被映射到 4mb。

我可以使用 C 或 C++。我的逻辑如下:

FILE *f = fopen("logfile.log", "r")
// go to file end to get current end position
fseek(f, 0, SEEK_END)
// ftell() always returns 4mb when actual file size is less than 4mb
// I need to get exact size of log file
currentEnd = ftell(f)
// go last read position
fseek(f, previousEnd, SEEK_SET)
//read from previousEnd to currentEnd with fread
// update last read position
previousEnd = currentEnd

有没有办法在 Windows 上获取现有映射文件的确切大小(以字节为单位)? 任何建议和想法表示赞赏。谢谢。

【问题讨论】:

  • GetFileSizeEx() 说什么?
  • 嗨 Medinoc,不幸的是,结果又是 4mb,它也没有说确切的当前实际大小。
  • 文件应该大于还是小于 4mb?如果是后者,我几乎没有希望(如果它映射到 4mb,那么它被认为至少有 4mb 长)。如果是前者,我也没有什么希望,因为 GetFileSizeEx 等应该工作......
  • 它以 4mb 大小开始,即使它只有一行,过了一会儿,随着行的到来,它超过了 4mb。所以我可以说它被认为至少有 4mb 长。
  • 我认为您没有正确使用术语“内存映射文件”。这看起来根本不像内存映射文件,它看起来像一个名为logfile.log 的常规文件。您正在使用沼泽标准 fopen 函数打开它。内存映射文件不仅仅是您为 I/O 打开的文件。

标签: c++ c windows memory-mapped-files


【解决方案1】:

没有办法,因为你错了。一旦您映射 4mb 的文件,系统就会将文件大小调整为 4mb。这很容易检查:

HANDLE file = CreateFile(_T("1.txt"), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
HANDLE mapping = CreateFileMapping(file, 0, PAGE_READWRITE, 0, 4*1024*1024, 0);
void* view = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);

运行此代码并关闭程序(为清楚起见省略了清理)。您将看到该文件现在为 4mb。显然,你不可能得到任何“职位”,因为根本没有。

我相信问题的根源在于您希望首先映射日志文件。不仅您遇到位置问题,当日志大小超过 4mb 时,您还会遇到另一个问题。为什么不像往常一样直接写入日志文件?

【讨论】:

  • 您好,感谢您的回复。让我再说一遍。我们有第三方服务,我想用它的日志文件交换一些关键字。我想定期检查文件大小,如果有任何更新,然后寻找最后读取位置并读取新行。但是每当我调用 ftell(f, 0, SEEK_END) 时,我都会得到 4mb 的文件大小。
  • 在记事本中打开日志,看看它的长度是多少。另外,请澄清“内存映射文件”的含义
  • 当我用记事本打开时,文件末尾的空格太多。它不是一个常规文件,当我定期尝试使用 fread() 读取时,它似乎在写入文件一段时间后缓冲输出。谢谢。
  • 我相信这些“空格”加起来是 4mb。所以文件大小是4mb。我仍然不确定“内存映射文件”是什么意思。
  • 如果文件的日志小于4mb,则文件的其他部分用空字符填充。因此,文件大小最初为 4mb,当文件填充有效日志时,它会增加 4mb。我不知道为什么服务填充仍然是文件的一部分,但我可以通过操纵文件位置来跟踪日志行。当我阅读时,我还会检查缓冲区的长度,如果我阅读空字符块,则返回 0。在这种情况下,我会在读取等之前返回文件的最后一个位置。感谢您的所有时间和考虑。
猜你喜欢
  • 2011-11-15
  • 2010-11-01
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多