Windows 系统中是不是存在未缓冲的 I/O?
Posted
技术标签:
【中文标题】Windows 系统中是不是存在未缓冲的 I/O?【英文标题】:Is there an un-buffered I/O in Windows system?Windows 系统中是否存在未缓冲的 I/O? 【发布时间】:2010-10-16 14:47:06 【问题描述】:我想找到没有缓冲区的低级 C/C++ API,相当于 linux 系统中的“write”。有吗?
fread、fwrite 等缓冲 I/O 不是我想要的。
【问题讨论】:
这是为了避免磁盘缓存,还是为了避免干扰管道和/或在写入时检查输出的那种缓冲? 【参考方案1】:http://www.codeproject.com/Articles/51678/Improve-responsiveness-in-Windows-with-the-FILE_FL
防止换出缓存的唯一方法是打开带有FILE_FLAG_NO_BUFFERING
标志的文件。但是,这要求磁盘 I/O 请求的大小可以被扇区大小(512 到 4096 字节)整除,这需要对大多数依赖于能够请求不同大小的应用程序进行大量重写。
这个项目包含一个插入式包装器,它提供了CreateFile_NB()
、ReadFile_NB()
、WriteFile_NB()
和CloseHandle_NB()
函数,这些函数负责在关闭打开以进行写入的文件时进行排队和调整文件大小。
http://msdn.microsoft.com/en-us/library/cc644950(v=vs.85).aspx
当使用 CreateFile 函数打开或创建文件时,可以指定 FILE_FLAG_NO_BUFFERING
标志来禁用系统缓存正在读取或写入文件的数据。虽然这可以完全直接地控制数据 I/O 缓冲,但对于文件和类似设备,必须考虑数据对齐要求。
【讨论】:
【参考方案2】:您可以使用_write
MSDN Page Here。
【讨论】:
【参考方案3】:流的级别尽可能低。 他们可以是无缓冲的。
int setvbuf( 文件*流, 字符 * 缓冲区, 整数模式, size_t 大小 );例子
setvbuf(stdout, (char *)NULL, _IONBF, 0); //无缓冲的标准输出这里是 vc2008 帮助文档的摘录。
setvbuf 函数允许程序控制流的缓冲和缓冲区大小。 stream 必须引用自打开后未进行 I/O 操作的打开文件。 buffer 指向的数组用作缓冲区,除非它为 NULL,在这种情况下 setvbuf 使用长度为 size/2 * 2 字节的自动分配的缓冲区。
模式必须是 _IOFBF 、 _IOLBF 或 _IONBF。如果 mode 为 _IOFBF 或 _IOLBF,则 size 用作缓冲区的大小。如果 mode 为 _IONBF,则流是无缓冲的,并且忽略大小和缓冲区。 mode 的值及其含义是:
_IOFBF 全缓冲;即buffer作为缓冲区,size作为缓冲区的大小。如果缓冲区为 NULL,则使用自动分配的缓冲区大小字节长。
_IOLBF 对于某些系统,这提供了行缓冲。但是,对于 Win32,其行为与 _IOFBF - Full Buffering 相同。
_IONBF 无论缓冲区或大小如何,都不使用缓冲区。
【讨论】:
我相信这是 C 库中的缓冲。它不影响操作系统级别或硬件级别的缓冲。【参考方案4】:POSIX write() 函数的 Win32 等效项是 @987654321@
。文档建议使用无缓冲文件 I/O,并建议使用 this page 获取更多信息。
【讨论】:
【参考方案5】:使用 FILE_FLAG_NO_BUFFERING 选项查看 CreateFile
【讨论】:
这不是一回事。默认情况下,Windows 中的 WriteFile() 已经类似于 Linux 上的 write()。两者都将让操作系统在将脏页刷新到磁盘之前对其进行缓冲。同样,在 Windows 或 Linux 上使用 fwrite 函数也会缓冲用户空间中的小块。因此 Windows 或 LInux 上的 fwrite() 具有双层缓冲区。默认情况下,Windows 上的 WriteFile() 在操作系统中具有单层缓冲,除非您还指定 FILE_FLAG_NO_BUFFERING,它会禁用操作系统缓冲。 Linux AFAIK 中没有与 FILE_FLAG_NO_BUFFERING 等效的功能。 简短的回答是,在 Linux 上使用 WriteFile() 等效于 write()。以上是关于Windows 系统中是不是存在未缓冲的 I/O?的主要内容,如果未能解决你的问题,请参考以下文章