如何判断一个文件是否已经被打开?

时间:2022-05-30 08:58:14
对于任意一个文件,如何来判断它是否已经被打开了?我曾试着通过独占的方式来试着打开目标文件,通过判断打开成功与否来进行判断,但发现还是不能准确判断出来,例如,一个TXT文件用Ultraedit打开后,被打开的文件然可以被删除。这时如果打开该文件肯定会失败,但文件其实还是已经被打开了。

15 个解决方案

#1


如果其他程序是以共享方式打开的,不好判断。。

#2


我有一个 Delphi 的代码,你直接转换成 C++ 的就可以

////////////////////////////////////////////////////////////////////////////////
// 功能     : 判断一个文件是否正在使用
// 参数     :
//
// 返回值   : True:正在使用 , False:没有使用或文件不存在
// 日期     : 2002/7/12
////////////////////////////////////////////////////////////////////////////////
function IsFileInUse(fName : string ) : boolean;
var
  HFileRes : HFILE;
begin
  Result := false;
  if not FileExists(fName) then
    exit;
  HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE,0, nil, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, 0);
  Result := (HFileRes = INVALID_HANDLE_VALUE);
  if not Result then
    CloseHandle(HFileRes);
end;

#3


sysinternals 的 Process Explorer

#4


在一般情况下,即然文件可以被删除,就说明它没被打开。假如我写了个程序,打开A.txt把它显示到界面上,然后关闭A.txt,但它的内容还在我的界面上显示,你能说A.txt还在被打开吗?

你说的UEdit也好,记事本也好,都是这种情况。

#5


对 楼上说的对  一定是UEdit,记事本等把文件又关闭了    否则不能删除的

#6


胡说,CreateFile里有个共享权限是FILE_SHARE_DELETE,这样就算打开了文件,还是可以被删除的。
不过记事本和UEdit的确是开了文件的。

#7


amei2000go(浪子) 你好。你说的方法我试过了:如果先执行你的代码,那么文件是不能再被打开的;可是,如果是文件已经被打开了,这行你的代码,还是可以打开文件。

#8


我的目的是这样的,就是首先判断一个文件是否已经被打开,如果打开则先关闭该文件,再替换该文件;否则,直接替换。
举个例子,现在有3个txt文件(A.txt,B.txt,C.txt),我想通过程序首先来判断B.txt是否已经被打开,如果打开了,则,首先关闭,然后用一个新的文件来替换;否则,直接用一个新的文件来替换。
另一个问题,如果用Notepad打开,在进程中会看到3个Notepad进程,我现在怎么知道这三个进程跟这三个文件的对应关系呢,也就是说,哪个进程打开了A.txt,哪个进程打开了B.txt。。。。。。

#9


试试这个
CFile f;
f.Open();
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
...
}

#10


晕,搞错了
那样子不行

#11


文件打开的时候如果是Windows系统,,应该有一个列表,记录着打开的句柄什么的吧,,,但不知道有没有相关的API可以查询,,,

#12


Notepad你很难有办法判断的,因为Notepad读完了以后就把hFile给CloseHandle了,这时文件你都可以直接删掉

Notepad是这样干的:
CreateFile(hFile)->CreateFileMapping(hMapFile)->CloseHandle(hFile)->MapViewOfFile->UnmapViewOfFile->CloseHandle(hMapFile)
除非你能在内存里面找到hMapFile这个内核对象

#13


你肯定是在做文件的后台加密,我也正在做这样的事

#14


做驱动就没有这些事了

#15


我估计UEdit采用了一个机制:就是把这个文件拷贝到一个临时文件夹中,然后打开,这样你就可以删除原来的那个,所以说Uedit打开的不是那个文件,是一个copy,如果你要判断文件有没有打开,我认为你的办法是可行的

#1


如果其他程序是以共享方式打开的,不好判断。。

#2


我有一个 Delphi 的代码,你直接转换成 C++ 的就可以

////////////////////////////////////////////////////////////////////////////////
// 功能     : 判断一个文件是否正在使用
// 参数     :
//
// 返回值   : True:正在使用 , False:没有使用或文件不存在
// 日期     : 2002/7/12
////////////////////////////////////////////////////////////////////////////////
function IsFileInUse(fName : string ) : boolean;
var
  HFileRes : HFILE;
begin
  Result := false;
  if not FileExists(fName) then
    exit;
  HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE,0, nil, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, 0);
  Result := (HFileRes = INVALID_HANDLE_VALUE);
  if not Result then
    CloseHandle(HFileRes);
end;

#3


sysinternals 的 Process Explorer

#4


在一般情况下,即然文件可以被删除,就说明它没被打开。假如我写了个程序,打开A.txt把它显示到界面上,然后关闭A.txt,但它的内容还在我的界面上显示,你能说A.txt还在被打开吗?

你说的UEdit也好,记事本也好,都是这种情况。

#5


对 楼上说的对  一定是UEdit,记事本等把文件又关闭了    否则不能删除的

#6


胡说,CreateFile里有个共享权限是FILE_SHARE_DELETE,这样就算打开了文件,还是可以被删除的。
不过记事本和UEdit的确是开了文件的。

#7


amei2000go(浪子) 你好。你说的方法我试过了:如果先执行你的代码,那么文件是不能再被打开的;可是,如果是文件已经被打开了,这行你的代码,还是可以打开文件。

#8


我的目的是这样的,就是首先判断一个文件是否已经被打开,如果打开则先关闭该文件,再替换该文件;否则,直接替换。
举个例子,现在有3个txt文件(A.txt,B.txt,C.txt),我想通过程序首先来判断B.txt是否已经被打开,如果打开了,则,首先关闭,然后用一个新的文件来替换;否则,直接用一个新的文件来替换。
另一个问题,如果用Notepad打开,在进程中会看到3个Notepad进程,我现在怎么知道这三个进程跟这三个文件的对应关系呢,也就是说,哪个进程打开了A.txt,哪个进程打开了B.txt。。。。。。

#9


试试这个
CFile f;
f.Open();
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
...
}

#10


晕,搞错了
那样子不行

#11


文件打开的时候如果是Windows系统,,应该有一个列表,记录着打开的句柄什么的吧,,,但不知道有没有相关的API可以查询,,,

#12


Notepad你很难有办法判断的,因为Notepad读完了以后就把hFile给CloseHandle了,这时文件你都可以直接删掉

Notepad是这样干的:
CreateFile(hFile)->CreateFileMapping(hMapFile)->CloseHandle(hFile)->MapViewOfFile->UnmapViewOfFile->CloseHandle(hMapFile)
除非你能在内存里面找到hMapFile这个内核对象

#13


你肯定是在做文件的后台加密,我也正在做这样的事

#14


做驱动就没有这些事了

#15


我估计UEdit采用了一个机制:就是把这个文件拷贝到一个临时文件夹中,然后打开,这样你就可以删除原来的那个,所以说Uedit打开的不是那个文件,是一个copy,如果你要判断文件有没有打开,我认为你的办法是可行的