如何从QFile或QSaveFile获取Windows HANDLE用于ReOpenFile?

时间:2018-05-05 16:11:48

标签: windows qt winapi handle qfile

给定QFileDevice个实例(QFileQSaveFile) - 如何获取文件的本机Windows HANDLE?这个句柄可以与ReOpenFile一起使用吗?

1 个答案:

答案 0 :(得分:1)

QFileDevice::handle()返回从QFSFileEnginePrivate::nativeHandle获得的C文件描述符(fd - 一个小整数)。该文件描述符是您从_open_osfhandle获得的。您需要使用_get_osfhandle返回HANDLE

struct FdHandle {
  int fd = -1;
  HANDLE handle = INVALID_HANDLE_VALUE;
  operator HANDLE() const { return handle; }
  bool isFdValid() const { return fd != -1; }
  bool isHandleValid() const { return handle != INVALID_HANDLE_VALUE; }
};

FdHandle windowsHandleOf(QFileDevice* dev) {
  auto fd = dev->handle(); 
  return {fd, (HANDLE)_get_osfhandle(fd)};
}

ReOpenFile可能会返回不同的文件句柄,因此您可能需要为其重新打开文件。重载ReOpenFile处理它:

struct ReOpenResult {
  enum { OK = 0, FileClosed = 10, NoHandle = 20, 
         OldHandle = 30, OpenFailed = 40 } rc;
  HANDLE handle = INVALID_HANDLE_VALUE;
  operator HANDLE() const { return handle; }
  explicit operator bool() const { return rc == OK; }
  bool isHandleValid() const { return handle != INVALID_HANDLE_VALUE; }
};

ReOpenResult ReOpenFile(QFile *file, DWORD access, DWORD shareMode, DWORD flags) {
  if (!file->isOpen())
    return {ReOpenResult::FileClosed};
  auto oldHandle = windowsHandleOf(file);
  if (oldHandle == INVALID_HANDLE_VALUE)
    return {ReOpenResult::NoHandle};
  auto newHandle = ReOpenFile(oldHandle, access, shareMode, flags);
  if (newHandle == INVALID_HANDLE_VALUE)
    return {ReOpenResult::OldHandle, oldHandle};
  if (!open(file, file->openMode(), newHandle))
    return {ReOpenResult::OpenFailed, oldHandle};
  return {ReOpenResult::OK, newHandle};
}

"失踪"需要open的{​​{1}}是:

HANDLE