Блокировка файлов с помощью C ++ в Windows - PullRequest
5 голосов
/ 12 мая 2009

У меня есть программа записи / чтения из файла, и я хочу заблокировать файл для других экземпляров моего приложения. Как я могу это сделать (в C ++ Visual Studio 2003)? Я попытался использовать _locking (), но также я сам не могу добраться до файла при попытке чтения / записи (в том же случае) Я знаю, что есть опция LockFile (), но не знаю, как правильно ее установить. Пожалуйста, помогите мне.

Ответы [ 3 ]

13 голосов
/ 12 мая 2009

Вы можете просто использовать Win32 API CreateFile , а затем не указывать права на совместное использование. Это гарантирует, что другие процессы не смогут получить доступ к файлу.

DWORD dwShareMode определяет тип общего доступа, который вы хотели бы, например, GENERIC_READ. Если вы укажете 0, это означает, что права на обмен не должны предоставляться.

Пример:

HANDLE hFile = CreateFile(_T("c:\\file.txt"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

Если вы хотите заблокировать только определенную часть файла, вы можете использовать LockFile или LockFileEx .

Пример:

 //Lock the first 1024 bytes
 BOOL bLocked = LockFile(hFile, 0, 0, 1024, 0);

Для блокировки на других платформах смотрите мой пост здесь .

1 голос
/ 25 мая 2012

Пройдя поиск в Интернете, я не нашел хороших примеров.

Вот два вызова CreateFile с намерением заблокировать файл на весь срок жизни процесса ... Я использую это вместе с CLimitSingleInstance , который использует CreateMutex для глобального имени mutex.

Первый вызов CreateFile пытается открыть его, второй создает его при необходимости. У меня есть немного более тщательная реализация. Я реализовал это в Qt, следовательно, вместо std :: cout и QDir :: tempPath () вместо qDrit :: tempPath () вместо q каким-то другим способом. QCritical ().

class SingleInstance
{
protected:
    DWORD  m_dwLastError;
    HANDLE m_hFile;
public:
    SingleInstance(const char *strMutexName) {  }

    bool attemptToLockTempFile()
    {
      QString lockFile = QDir::tempPath() + "/My.exe.lock";
      m_hFile = CreateFileA(lockFile.toLocal8Bit().data(), GENERIC_READ, 0, 
                                NULL, OPEN_EXISTING, 0, NULL);
      DWORD dwLastError = GetLastError();
      if(m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE)
      {
          return true;
      }
      else
      {
          if(dwLastError == ERROR_FILE_NOT_FOUND )
          {
              m_hFile = CreateFileA(lockFile.toLocal8Bit().data(), GENERIC_READ, 
                                        0, NULL, CREATE_NEW, 0, NULL);
              dwLastError = GetLastError();

              if(m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE)
              {
                  return true;
              }
              else if(dwLastError == ERROR_SHARING_VIOLATION)
              {
                  qCritical() << "Sharing Violation on My.exe.lock";
              }
              else
              {
                  qCritical() << "Error reading" << "My.exe.lock" << "-" << dwLastError;
              }
          }
          else if(dwLastError == ERROR_SHARING_VIOLATION)
          {
              qCritical() << "Sharing Violation on My.exe.lock";
          }
          else
          {
              qCritical() << "Unable to obtain file lock -" << dwLastError;
          }
          return false;
      }
    }

    ~SingleInstance()
    {
        if ( m_hFile != NULL && m_hFile != INVALID_HANDLE_VALUE)
        {
            ::CloseHandle(m_hFile); //Do as late as possible.
            m_hFile = NULL;
        }
    }
}

Вот что у вас будет в верхней части вашей основной функции:

SingleInstance g_SingleInstanceObj(globalId_QA);

// Makes sure that the program doesn't run if there is another 
// instance already running
if (g_SingleInstanceObj.IsAnotherInstanceRunning())
{
    return 0;
}
1 голос
/ 12 мая 2009

Требуется LockFileEx () (эксклюзивная блокировка файлов). Взгляните на это обсуждение из книги по безопасному программированию для C и C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...