我应该使用什么C ++写入功能?

时间:2011-12-24 01:41:06

标签: c++ winapi

我不想在那里使用XML库解析器,所以你能给我一些建议,用于将数据写入XML文件吗?我将大量调用write函数,因此write函数应该能够跟踪最后的写入位置,并且它不应该占用太多资源。我在下面有两个不同的写,但我无法跟踪最后写入位置,除非我必须读取文件直到文件结尾。

情况#1

FILE *pfile = _tfopen(GetFileNameXML(), _T("w"));

if(pfile)
{
    _fputts(TEXT(""), pfile);
}

if(pfile)
{
    fclose(pfile);
    pfile = NULL;
}

例#2

HANDLE hFile = CreateFile(GetFileNameXML(), GENERIC_READ|GENERIC_WRITE,
    FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if(hFile != INVALID_HANDLE_VALUE)
{
    WriteFile(hFile,,,,,);
}

CloseHandle(hFile);

感谢。

2 个答案:

答案 0 :(得分:2)

如果您只需要编写一些文本文件,请使用C ++的标准库文件工具。此处的示例将非常有用:http://www.cplusplus.com/doc/tutorial/files/

答案 1 :(得分:-1)

首先,您对使用标准XML处理库有何厌恶?

接下来,如果你决定推出自己的,绝对不要直接使用Win32 API - 至少除非你要用大块写出生成的XML,否则你将要实现你的自己的缓冲层。

处理小文件并不重要,但你特别提到了良好的性能和许多对write函数的调用。 WriteFile具有相当大的开销,它做了大量的工作并且涉及用户 - >内核 - >用户模式切换,这是昂贵的。如果您正在处理“正常大小”的XML文件,您可能无法看到很大差异,但如果您生成的是大小很大的转储,那么一定要记住这一点。

你提到跟踪最后一个写位置 - 首先关闭,应该很容易......使用FILE缓冲区ftell,使用原始Win32 API SetFilePointerEx - 用{{1}调用它}和liDistanceToMove=0,并在写入后获得当前文件位置。但你为什么需要这个呢?如果您要流出一个XML文件,通常应该继续流式传输,直到您完成写入 - 您是否关闭并重新打开文件?或者您是否正在编写一个有效的XML文件,以便在以后插入更多数据?

至于Win32文件函数的开销,它可能与您的情况相关或不相关(取决于您正在处理的文件的大小),但对于较大的文件,它很重要 - 包括下面的一个微型基准测试,简单地使用ReadFile将文件读入内存,允许您从命令行指定不同的缓冲区大小。在运行该工具时,查看Process Explorer的IO选项卡很有意思。以下是我的可爱笔记本电脑的一些统计数据(Win7-SP1 x64,core2duo P7350 @ 2.0GHz,4GB内存,120GB Intel-320 SSD)。

把它当作微观基准。在您的特定情况下,性能可能会或可能不重要,但我确实相信这些数字表明Win32文件API有相当大的开销,并且对您自己的缓冲有帮助。

使用完全缓存的2GB文件:

BlkSz   Speed
32      14.4MB/s
64      28.6MB/s
128     56MB/s
256     107MB/s
512     205MB/s
1024    350MB/s
4096    800MB/s
32768   ~2GB/s

“如此大,只有缓存未命中”4GB文件:

BlkSz   Speed       CPU
32      13MB/s      49%
64      26MB/s      49%
128     52MB/s      49%
256     99MB/s      49%
512     180MB/s     49%
1024    200MB/s     32%
4096    185MB/s     22%
32768   205MB/s     13%

请记住,49%的CPU使用率意味着一个CPU内核几乎完全挂钩 - 单个线程无法真正推动机器更加困难。请注意第二个表中4kb缓冲区的病理行为 - 它是可重现的,我没有解释它。

Crappy micro-benchmark code to:

dwMoveMethod=FILE_CURRENT