【问题标题】:In Windows, should I use CreateFile or fopen, portability aside?在 Windows 中,除了可移植性,我应该使用 CreateFile 还是 fopen?
【发布时间】:2010-06-14 14:58:20
【问题描述】:

有什么区别,在什么情况下,其中一种会在某些方面表现得更好?

【问题讨论】:

    标签: windows winapi fopen createfile


    【解决方案1】:

    首先fopen函数只能用于对文件的简单可移植操作。

    另一边的CreateFile不仅可以用于对文件的操作,还可以对目录(使用相应的选项)、管道和各种Windows设备进行操作。

    CreateFile 有很多额外的有用开关,如FILE_FLAG_NO_BUFFERINGFILE_ATTRIBUTE_TEMPORARYFILE_FLAG_SEQUENTIAL_SCAN,它们在不同的场景中非常有用。

    您可以将CreateFile 与长于MAX_PATH 字符的文件名一起使用。这对于某些服务器应用程序或必须能够打开任何文件的服务器应用程序(例如病毒扫描程序或备份应用程序)可能很重要。这是通过使用命名空间语义来实现的,尽管这种模式有其自身的问题,例如能够实际创建一个名为 ".."L"\xfeff\x20\xd9ab" 的文件(祝你好运,稍后尝试删除它们)。

    您可以在不同的安全场景中使用CreateFile。我的意思不仅仅是安全属性的使用。如果当前进程具有 SE_BACKUP_NAME 或 SE_RESTORE_NAME 权限(就像管理员通常拥有的那样)并启用此权限,则可以使用 CreateFile 打开任何文件,也可以是您无法通过安全描述符访问的文件。

    如果你只想读取一个文件的内容,你可以使用CreateFileCreateFileMappingMapViewOfFile来创建文件映射。然后您可以像处理内存块一样处理文件,这可能会提高应用程序的速度。

    该功能还有其他用途,在the corresponding MSDN article.中有详细介绍

    所以我可以总结一下:只有当您有硬的可移植性要求或需要将FILE* 传递给某个外部库时,您才必须使用fopen。在所有其他情况下,我建议您使用CreateFile。 为获得最佳效果,我还建议专门学习 Windows API,因为您可以找到许多有用的功能。

    更新:与您的问题没有直接关系,但我也建议您看一下从 Windows Vista 开始支持的 transactional I/O 函数。使用此功能,您可以将一堆对文件、目录或注册表的操作作为一个不可中断的事务提交。这是一个非常强大和有趣的工具。如果您现在还没有准备好使用事务 I/O 功能,您可以从 CreateFile 开始,稍后将您的应用程序移植到事务 I/O。

    【讨论】:

      【解决方案2】:

      这实际上取决于您编写的程序类型。如果它应该是便携式的,fopen 将使您的生活更轻松。 fopen 将致电 CreateFile “幕后”。

      一些更高级的选项(缓存控制、文件访问控制等)只有在您使用 Win32 API 时才可用(它们依赖于 Win32 文件句柄,而不是 stdio 中的 FILE 指针),所以如果您正在编写一个纯 Win32 应用程序,您可能需要使用 CreateFile。

      【讨论】:

        【解决方案3】:

        CreateFile 让你

        • 为异步 I/O 打开文件
        • 传递优化提示,如 FILE_FLAG_SEQUENTIAL_SCAN
        • 设置安全性和继承设置而不会出现线程问题

        它们不返回相同的句柄类型,使用 fopen/FILE 对象,您可以调用其他运行时函数,例如 fputs(以及将其转换为“本机”文件句柄)

        【讨论】:

          【解决方案4】:

          尽可能选择支持 RAII 的面向对象的包装器,例如 fstream 或 boost 文件 IO 对象。

          当然,你应该关心共享模式,所以 fopen() 和 STL 是不够的。

          【讨论】:

            猜你喜欢
            • 2012-09-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-25
            • 1970-01-01
            相关资源
            最近更新 更多