在Windows中删除打开的文件(创建匿名文件)?

时间:2015-03-31 07:53:44

标签: windows file unlink

在Linux下,我的程序将执行以下操作:

  • 进程1打开一个文件(例如,通过将其映射到内存中)。我们称这个文件为#1
  • 进程2取消链接文件,并创建一个具有相同名称的新文件。我们称这个文件为#2。
  • 进程1继续使用文件#1。当它关闭时,它被删除(因为它没有链接)。进程1继续使用文件#1中的内容,但不会看到文件#2中的内容。
  • 当两个进程都退出时,文件#2仍保留在磁盘上。

我想在Windows中实现相同的语义。阅读this question之后,我认为FILE_SHARE_DELETE基本上就是这样做的。是否用FILE_SHARE_DELETE打开文件,还是需要考虑更多内容?

上面的执行流程只是一个例子,我知道在Windows中还有其他方法可以解决这个问题,但我想了解如何在Windows和Linux之间移植这些代码。

编辑:澄清:用例是为不同的不相关文件重用文件名,但让现有进程保留其数据(例如,考虑配置文件的事务更新),并使文件匿名(未命名) ,但继续像匿名内存映射一样使用它。我再次知道在Windows上通过其他方式都可以实现,但我试图找到一种可跨平台移植的方式。

1 个答案:

答案 0 :(得分:1)

您可以通过结合使用CreateFile,CreateFileMapping和MapViewOfFile来实现此目的。 MapViewOfFile将为您提供磁盘上文件支持的文件的内存映射缓冲区。

从不同进程执行代码时,将在c:\ temp \ temp.txt

文件中写入最后一个结束进程的进程ID

int main()
{
	TCHAR szMsg[256];
	HANDLE hMapFile;
	LPCTSTR pBuf;

	HANDLE hFile = CreateFileW(
		L"C:\\Temp\\temp.txt", 
		GENERIC_WRITE|GENERIC_READ, 
		FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, 
		NULL, 
		CREATE_ALWAYS, 
		FILE_ATTRIBUTE_NORMAL,NULL);


	hMapFile = CreateFileMapping(
		hFile,					 // Handle of file opened with rw access
		NULL,                    // default security
		PAGE_READWRITE,          // read/write access
		0,                       // maximum object size (high-order DWORD)
		BUF_SIZE,                // maximum object size (low-order DWORD)
		szName);                 // name of mapping object

	if (hMapFile == NULL)
	{
		printf( "Could not create file mapping object (%d).\n", GetLastError());
		return 1;
	}
	pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object
		FILE_MAP_ALL_ACCESS, // read/write permission
		0,
		0,
		BUF_SIZE);

	if (pBuf == NULL)
	{
		printf("Could not map view of file (%d).\n", GetLastError());
		CloseHandle(hMapFile);
		return 1;
	}
	
	wsprintfW(szMsg, L"This is process id %d", GetCurrentProcessId());
	CopyMemory((PVOID)pBuf, szMsg, (wcslen(szMsg) * sizeof(TCHAR)));

	MessageBoxW(NULL, szMsg, L"Check", MB_OK);

	UnmapViewOfFile(pBuf);
	CloseHandle(hMapFile);
	CloseHandle(hFile);
	return 0;


}

确保使用GENERIC_READ | GENERIC_WRITE访问权限打开文件,并允许FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE访问后续打开。

另请注意在CreateFile中使用CREATE_ALWAYS,它将删除旧文件并在每次调用CreateFile时打开一个新文件。这是你谈到的'unlink'效果。

代码灵感来自Creating Named Shared Memory at msdn