我需要在Windows中读取文件并避免任何操作系统级锁定,以便用户即使在我的应用程序正在读取文件时也可以删除该文件。
通过C ++,Python,Java等使用典型的读取操作,通过procmon进行评估时显示相同的Winapi调用序列:
如果我尝试在步骤1和3之间通过资源管理器删除文件(基本上在CreateFile之后和CloseFile之前),我将使用"文件正在使用"错误。
但是,我注意到当Dropbox读取要上传到服务器的文件时,序列为:
答案 0 :(得分:0)
这种创建 - 关闭 - 读取语义应该由文件映射到应用程序的地址空间中的内存区域的事实引起。当应用程序尝试从该区域读取时,操作系统从文件中读取必要的数据并将其传递给应用程序(数据显示在映射文件的内存区域中)。
内存映射文件由文件映射对象(称为内核世界中的一个部分)支持。给定文件句柄,您可以通过 SELECT 1 as Id, (SELECT * FROM #OR_MK FOR XML PATH('MK'), root('OR_MK') ) as OR_MK
,(SELECT * FROM #OR_CA FOR XML PATH('CA'), root('OR_CA') ) as OR_CA
-- ,ISNULL( (SELECT * FROM #OR_RS FOR XML PATH('RS'), root('OR_RS')), (SELECT ISNULL(ContactCode,'') , ISNULL(EmailPaper,'') , ISNULL(ShortEmail,'') , ISNULL(WebSite,'') , ISNULL(Providers,'') FROM #OR_RS FOR XML AUTO)) as OR_RS
,(SELECT * FROM #OR_RS FOR XML PATH('RS'), root('OR_RS')) as OR_RS
,(SELECT * FROM #OR_DC FOR XML PATH('DC'), root('OR_DC') ) as OR_DC
,(SELECT * FROM #BENEFICIARY FOR XML PATH('BEN'), root('BENEFICIARY') ) as BENEFICIARY
,(SELECT * FROM #MK_REPORT for XML PATH('REP'), root('MK_REPORT')) as MK_REPORT
创建此类对象,并通过CreateFileMapping
将其映射到您的地址空间(也存在一些Ex变体)。文件映射对象保留对其映射的文件的额外引用。因此,在为文件创建文件映射对象之后,您可以关闭文件句柄并通过文件映射对象读取文件。