2

在我当前的项目中,我们需要检查文件是否仍在复制。

我们已经开发了一个库,它将在特定文件夹以及相应的文件路径上向我们提供诸如 file_added 、 file_removed 、 file_modified 、 file_renamed 之类的操作系统通知。

这里的问题是,假设您添加 1 GB 文件,它会在复制文件时发出多个通知,例如 file_added 、 file_modified 、 file_modified 。

现在我决定通过检查文件是否正在复制来超越这些通知。基于此,我将忽略事件。

我在 C++ 中编写了下面的函数,它告诉文件是否正在被复制,它以文件路径作为输入。详细信息:-基本上它使用Windows API“CreateFile”来获取文件句柄。如果我们无法获取句柄,则确定为正在复制文件。

问题:- 对于一些较大的文件,例如 2 GB 的 .rar 和 .exe 格式,这不起作用。你能告诉我这是正确的方法吗?如果不欣赏其他方法。

bool isFileBeingCopied(const boost::filesystem::path &filePath)
{
     //Log(INFO, "Checking if the given file is being copied or not for the file [%s]",filePath.string().c_str());
     HANDLE hFile = ::CreateFile(filePath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
     DWORD dwLastError = GetLastError();

     if(hFile == NULL && hFile == INVALID_HANDLE_VALUE)
     {
          Log(INFO, "Gained invalid handle on the file - hence determining it, as being copied file [%s]",filePath.string().c_str());
          return true;
     }
     else
     {
          if(dwLastError == ERROR_SUCCESS )
          {
                CloseHandle(hFile);
                Log(INFO, "Able to gain the handle on the file - hence determining it, as copied file [%s]",filePath.string().c_str());
                return false;
          }
          else
          {
              Log(INFO, "Not able to gain the handle for the file - hence determining it, as being copied file [%s]",filePath.string().c_str());
              return true;
          }
     }               
}
4

3 回答 3

1

使用boost 文件系统库,我们可以找出文件是否被复制。基本上 boost::filesystem::fstream 类为 I/O 操作打开文件。当前正在复制文件时,boost lib 无法打开文件并且 is_open() 方法将返回 false。因此,在这种情况下,我们可以安全地假设文件当前正在被复制。如果文件也损坏或损坏,我们最终会处于这种情况。

在所有其他情况下,is_open() 返回 true,我们可以认为文件复制已完成(在此用例中)希望此代码有所帮助。

boost::filesystem::fstream fileStream(filePath, std::ios_base::in | std::ios_base::binary);

if(fileStream.is_open())
{
    //We could open the file, so file is good
    //So, file is not getting copied.
}
else
{
    //Wait, the file is currently getting copied. 
}

编辑:添加了更多解释

于 2013-07-12T05:19:01.887 回答
1

除非您自己复制文件,否则无法从外部确定文件的复制状态。您可能必须使用计时器来检测文件修改事件何时停止发送给您。

于 2012-10-06T18:03:34.147 回答
0

如果该文件先前已以dwShareMode= 0, IOW 以独占访问模式打开(并且仍然如此),则您将无法再次打开它,直到它关闭,无论文件是否正在被复制(=写入) 与否,因此true不能依赖函数的返回值。

请注意,如果CreateFile()成功,则调用CloseHandle()并返回false。在此之后,文件可以立即被另一个进程打开以进行写入,并且false由于可能存在这种竞争条件,因此不能依赖返回的值。如果你想阻止它,你不能关闭句柄,直到你不再有兴趣拥有对文件的独占访问权。

因此,这显然不是准确确定文件是否被复制(=写入)的正确方法。这似乎是一件毫无意义的事情。

在我看来,您试图在这里解决错误的问题。您决定检查文件是否被复制(=写入)的真正问题是什么?如果你告诉我们,我们也许可以帮助解决这个真正的问题。

于 2012-10-06T10:51:59.783 回答