在 Windows 中,除了可移植性之外,我应该使用 CreateFile 还是 fopen?
有哪些差异,在什么情况下其中一个或另一个在某种程度上会被证明更优越?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
有哪些差异,在什么情况下其中一个或另一个在某种程度上会被证明更优越?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(4)
首先,函数
fopen
只能用于对文件进行简单的可移植操作。另一端的
CreateFile
不仅可以用于对文件的操作,还可以用于对目录(使用相应选项)、管道和各种Windows设备的操作。CreateFile
有很多其他有用的开关,例如FILE_FLAG_NO_BUFFERING
、FILE_ATTRIBUTE_TEMPORARY
和FILE_FLAG_SEQUENTIAL_SCAN
,它们在不同的场景。您可以将
CreateFile
与文件名长度超过MAX_PATH
个字符的文件一起使用。对于某些服务器应用程序或必须能够打开任何文件的应用程序(例如病毒扫描程序或备份应用程序)来说,这可能很重要。这是通过使用命名空间语义来实现的,尽管此模式有其自身的问题,例如实际创建名为".."
或L"\xfeff\x20\xd9ab" (祝你稍后尝试删除它们好运)。
您可以在不同的安全场景中使用
CreateFile
。我的意思不仅仅是安全属性的使用。如果当前进程具有 SE_BACKUP_NAME 或 SE_RESTORE_NAME 权限(管理员通常拥有的权限)并启用此权限,则可以使用CreateFile
打开任何文件,也可以是您无权访问的文件通过安全描述符。如果您只想读取文件的内容,可以使用
CreateFile
、CreateFileMapping
和MapViewOfFile
来创建文件映射。然后,您可以像处理内存块一样处理文件,这可能会提高应用程序的速度。该函数还有其他用途,在 相应的 MSDN 文章。
所以我可以总结一下:仅当您有硬可移植性要求或者需要将
FILE*
传递给某些外部时库,那么你必须使用fopen
。在所有其他情况下,我建议您使用CreateFile
。为了获得最佳结果,我还建议专门学习 Windows API,因为您可以找到很多有用的功能。
更新:与您的问题没有直接关系,但我也建议您看一下事务性 I/O 功能。使用此功能,您可以将一系列文件、目录或注册表操作作为一个不可中断的事务提交。这是一个非常强大且有趣的工具。如果您现在还没有准备好使用事务性 I/O 函数,则可以从
CreateFile
开始,稍后将应用程序移植到事务性 I/O。First of all the function
fopen
can be used only for simple portable operations with files.CreateFile
on the other side can be used not only for operations with files, but also with directories (with use of corresponding options), pipes and various Windows devices.CreateFile
has a lot of additional useful switches, likeFILE_FLAG_NO_BUFFERING
,FILE_ATTRIBUTE_TEMPORARY
andFILE_FLAG_SEQUENTIAL_SCAN
, which can be very useful in different scenarios.You can use
CreateFile
with a filename longer thatMAX_PATH
characters. It can be important for some server applications or ones which must be able to open any file (a virus scanner or a backup application for example). This is enabled by using namespace semantics, though this mode has its own concerns, like ability to actually create a file named".."
orL"\xfeff\x20\xd9ab"
(good luck trying to delete them later).You can use
CreateFile
in different security scenarios. I mean not only usage of security attributes. If current process has SE_BACKUP_NAME or SE_RESTORE_NAME privilege (like Administrators typically have) and enable this privilege, one can useCreateFile
to open any file also a file to which you have no access through security descriptor.If you only want to read the content of a file, you can use
CreateFile
,CreateFileMapping
andMapViewOfFile
to create file mapping. Then you can work with a file as with a block of memory, which can possibly increase your application's speed.There are also other uses of the function, which are described in detail in the corresponding MSDN article.
So I can summarize: only if you have a hard portability requirements or if you need to pass a
FILE*
to some external library, then you have to usefopen
. In all other cases I would recommend you to useCreateFile
.For best results, I would also advise to learn Windows API specifically, as there are many features that you can find a good use for.
UPDATED: Not directly related to your question, but I also recommend you to take a glance at transactional I/O functions which are supported starting with Windows Vista. Using this feature, you can commit a bunch of operation with files, directories or registry as one transaction that cannot be interrupted. It is a very powerful and interesting tool. If you are not ready now to use the transactional I/O functions, you can start with
CreateFile
and port your application to transactional I/O later.这实际上取决于您正在编写的程序类型。如果它是便携式的,
fopen
将使您的生活更轻松。fopen
将在“幕后”调用CreateFile
。一些更高级的选项(缓存控制、文件访问控制等)仅在您使用 Win32 API 时才可用(它们依赖于 Win32 文件句柄,而不是 stdio 中的 FILE 指针),因此,如果您正在编写纯 Win32 应用程序,您可能需要使用 CreateFile。
That really depends on what type of program you are writing. If it is supposed to be portable,
fopen
will make your life easier.fopen
will callCreateFile
"behind the scenes".Some more advanced options (cache control, file access control, etc) are only available if you are using the Win32 API (they depend on the Win32 file handle, as opposed to the
FILE
pointer in stdio), so if you are writing a pure Win32 application, you may want to use CreateFile.CreateFile 允许您
它们不会返回相同的句柄类型,使用 fopen/FILE 对象您可以调用其他运行时函数,例如 fputs(以及将其转换为“本机”文件句柄)
CreateFile lets you
They don't return the same handle type, with fopen/FILE object you can call other runtime functions such as fputs (as well as converting it to a "native" file handle)
只要有可能,首选支持 RAII 的面向对象包装器,例如 fstream 或 boost 文件 IO 对象。
当然,您应该关心共享模式,因此 fopen() 和 STL 是不够的。
Whenever possible, prefer object oriented wrappers that support RAII, like fstream or boost file IO objects.
You should, of course, care about the share mode, so fopen() and STL are insufficient.