我看到标准C无法判断文件是否在另一个进程中已经打开。因此,答案应该包含每个平台的多个示例。尽管如此,我需要在Visual C++ / Windows中进行检查。
我看到标准C无法判断文件是否在另一个进程中已经打开。因此,答案应该包含每个平台的多个示例。尽管如此,我需要在Visual C++ / Windows中进行检查。
Windows:尝试以独占模式打开文件。如果成功,表示没有其他人打开该文件,也无法打开该文件。
HANDLE fh;
fh = CreateFile(filename, GENERIC_READ, 0 /* no sharing! exclusive */, NULL, OPEN_EXISTING, 0, NULL);
if ((fh != NULL) && (fh != INVALID_HANDLE_VALUE))
{
// the only open file to filename should be fh.
// do something
CloseHandle(fh);
}
微软公司表示:dwShareMode。
对象的共享模式,可以是读、写、两者皆有、删除、所有这些或者没有(请参考下表)。
如果此参数为零并且CreateFile成功,则该对象无法共享,直到关闭句柄之前也无法再次打开。
您不能请求与具有打开句柄的打开请求中指定的访问模式冲突的共享模式,因为这会导致以下共享违规:ERROR_SHARING_VIOLATION。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx
扩展内容: 如何删除一个没有任何人以读/写方式打开的文件系统中的(非只读)文件?
需要访问权限文件 FILE_READ_ATTRIBUTES,而不是删除权限。DELETE 权限可能会在 smb 共享(对于 MS Windows 服务器)上引起问题——CreateFile 将保留仍然打开的 FileHandle /Device/Mup:xxx 文件名,不管 Mup 是什么意思。如果使用文件访问权限 FILE_READ_ATTRIBUTES,就不会出现这种情况。 使用 FILE_FLAG_OPEN_REPARSE_POINT 删除文件名。否则,您将会删除符号链接的目标——这通常不是您想要的。
HANDLE fh;
fh = CreateFile(filename, FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE /* no RW sharing! */, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_DELETE_ON_CLOSE, NULL);
if ((fh != NULL) && (fh != INVALID_HANDLE_VALUE))
{
DeleteFile(filename); /* looks stupid?
* but FILE_FLAG_DELETE_ON_CLOSE will not work on some smb shares (e.g. samba)!
* FILE_SHARE_DELETE should allow this DeleteFile() and so the problem could be solved by additional DeleteFile()
*/
CloseHandle(fh); /* a file, which no one has currently opened for RW is delete NOW */
}
如何处理一个已经打开的文件?如果这个文件已经被打开,而你又有unlink权限,那么你会留下一个文件,后续的打开操作将导致ACCESS_DENIED错误。如果你有一个临时目录,那么将filename重命名为tempdir/filename.delete并删除tempdir/filename.delete可能是一个好主意。
除非其他进程明确禁止访问文件,否则无法确定。在MSVC中,您可以使用_fsopen()
,并将_SH_DENYRD
指定为shflag参数来实现。在多任务操作系统上,关注是否打开了未锁定的文件的概念是深度错误的。它可能会在您发现它没有被锁定的一微秒后被打开。这也是Windows没有IsFileLocked()函数的原因。
如果您需要对文件进行同步访问,则需要使用命名互斥对象,使用CreateMutex()函数。
如果你设法弄清楚了,那很好;否则,你可能会对捕捉文件打开/关闭操作感兴趣:Windows API提供了大量所谓的Hooks:http://msdn.microsoft.com/en-us/library/ms997537.aspx。 Hooks允许您在系统中发生某些事情时请求通知。我相信有一种方法可以告诉您何时程序-整个系统-打开文件。因此,您可以在您监听挂钩的持续时间内制作自己的文件打开列表。我不确定,但我怀疑这可能就是FileMon所做的事情。
包括hook函数在内的Windows API可以从C中访问。系统范围的钩子将要求您创建一个DLL,以便在您的程序旁边加载。
希望这些提示能帮助您入门。
对于Windows,这段代码同样适用:
boolean isClosed(File f) { return f.renameTo(f); }
打开的文件无法更名,以相同的名称重命名不会引起另一个错误。因此,如果重命名成功,实际上没有做任何事情,您就知道该文件未被打开。
std::rename
重命名文件,Windows会允许重命名该文件,即使它已经被打开了。 - Angie Quijano bool IsFileDownloadComplete(const std::wstring& dir, const std::wstring& fileName)
{
std::wstring originalFileName = dir + fileName;
std::wstring tempFileName = dir + L"temp";
while(true)
{
int ret = rename(convertWstringToString(originalFileName).c_str(), convertWstringToString(tempFileName).c_str());
if(ret == 0)
break;
Sleep(10);
}
/** File is not open. Rename to original. */
int ret = rename(convertWstringToString(tempFileName).c_str(), convertWstringToString(originalFileName).c_str());
if(ret != 0)
throw std::exception("File rename failed");
return true;
}
这个应该不难吧,伙计们。
做这个:
try{
File fileout = new File(path + ".xls");
FileOutPutStream out = new FileOutPutStream(fileout);
}
catch(FileNotFoundException e1){
// if a MS Windows process is already using the file, this exception will be thrown
}
catch(Exception e){
}