2009-05-18 11 views
0

アンマネージド C++でプログラムを作成する方法を探しています。これは、ファイルがロックされていない(使用中でなくなった)ときまで待っています。私はこれを行う方法を見つける運がなかった、どんな助けも高く評価されるだろう!ファイルのロックを監視して、ファイルのロックを確認するにはどうすればよいですか? [C++]

UPDATE:私は...以下を参照してください、あなたはどう思うかを教え、自分の質問に答えたかもしれ

UPDATE:それはまだであればすべてのことが本当に重要なファイルが書き込み可能であるということです、それは問題ではありません。使用中で。

答えて

0

これは私の問題の解決策の1つですが、誰もこれに問題がありますか?

#include <iostream> 
#include <fstream> 
#include <windows.h> 
using namespace std; 
void main(int argc, char ** argv) { 
    if (argc < 2 || argc > 2) { 
     return; 
    } 

    ofstream myfile; 
    myfile.open(argv[1], ios_base::app); 
    while (!myfile.is_open()) { Sleep(100); myfile.open(argv[1], ios_base::app); } 
    myfile.close(); 

    // file should now be unlocked.. 
} 

もう一度おねがいします!

更新:コードをより完全に変更しました。

+0

待っているように見えませんか? – Andomar

+0

is_openブロックは、あなたが望んでいると思っていません。 –

+0

いいえ、私は使用しているバージョンでスリープ(100)していません。 –

1

成功するまで::CreateFile()を5秒ごとに呼び出すループを作成します。 dwShareMode引数に0を渡して、ファイルを開いた他のプロセスがないことを確認します。

+0

このストンプは私が監視しようとしているファイルの上にするファイルの通知をロックするでしょうか? –

+0

これは、ストンプの意味ですか? – Andomar

+0

元のファイルを上書きします。 –

2

このようなことは、CPUサイクルを無駄にすることなく待機します。

HANDLE h = FindFirstChangeNotification("C:\Path to folder holding file", FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE); 

while(true) 
{ 
    if (CheckLockFile("C:\Path to file")) 
    { 
     // Do something 
     break; 
    } 

    WaitForSingleObject(h, APPROPRIATE_TIMEOUT_VALUE); 
    FindNextChangeNotification(h); 
} 

bool CheckLockFile(char* FilePath) 
{ 
    HANDLE fh = CreateFile(FilePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0,NULL); 
    if (fh == INVALID_HANDLE_VALUE) 
    { 
     return false; 
    } 
    CloseHandle(fh); 

    return true; 
} 

これは、ファイルのロックが設定されているアプリケーションが書き込み用に開いていることを前提としています。

+1

これはまったく防水ではありません:FILE_NOTIFY_CHANGE_LAST_WRITEは、読み取り専用で開いたファイルが閉じられたときにトリガーしません。ディスクキャッシュが十分にフラッシュされた場合にのみ動作します。システムが非常にビジー状態のときに通知が失われる可能性があります。 – Andomar

0

別のプログラムがロックを解除した後、ファイルにアクセスしたいようです。 UNIX(とCygwin)では、単にファイルをロックするだけでこの動作が実現します。 ScopeGuardのようなものを使用して

File_lockerを不要にすることができますが、ScopeGuardを使用していない場合は、次のように行く:

UNIX:

#include <stdexcept> 
#include <string> 
#include "sys/file.h" //flock 
#include "sys/fcntl.h" //open 

class File_locker { 
    int file_descriptor; 
    public: 
    File_locker(std::string filename) 
    { 
     // you can use errno to determine why the open/flock failed, 
     // but this is a demo, not production code 

     file_descriptor = ::open(filename.c_str(), O_RDWR); 
     if (file_descriptor < 0) 
      throw std::runtime_error((std::string("unable to open file ") 
       + filename).c_str()); 
     if (::flock(file_descriptor, LOCK_EX)) { 
      ::close(file_descriptor); 
      throw std::runtime_error((std::string("unable to flock file ") 
       + filename).c_str()); 
     } 
    } 
    ~File_locker() 
    { 
     ::flock(file_descriptor, LOCK_UN); // don't forget to unlock 
     ::close(file_descriptor); 
    } 
}; 

のWindowsでは、あなたがファイルをポーリングする必要が表示されます。

のWindows:

#include <string> 
#include "windows.h" 

class File_locker { 
    HANDLE file_handle; 
    static const int MAX_TRIES = 10; 
    static const int SLEEP_INTERVAL = 500; 

    public: 
    File_locker(std::string filename) 
    { 
     // you can use GetLastError() to determine why the open failed, 
     // but this is a demo, not production code 
     for (int i = 0; i < MAX_TRIES; ++i) { 
      file_handle = ::CreateFile(filename.c_str(), 
             GENERIC_READ | GENERIC_WRITE, 
             0, 
             NULL, 
             OPEN_EXISTING, 
             FILE_ATTRIBUTE_NORMAL, 
             NULL); 
      if (file_handle != INVALID_HANDLE_VALUE) 
       return; 
      ::Sleep(SLEEP_INTERVAL); 
      } 
      throw std::runtime_error((std::string("unable to open file ") 
       + filename).c_str()); 
    } 
    ~File_locker() 
    { 
     ::CloseHandle(file_handle); 
    } 
}; 

ので、同じようにそれを使用します。

#include <fstream> 
#include <stdexcept> 

// .. define File_locker, as above 

int main() 
{ 
    try { 
     File_locker fl("filename.txt"); 
     // once fl is constructed, nobody else has the file locked 
     std::fstream file("filename.txt"); 
     // ... 
     return 0; 
    } 
    catch (std::runtime_error& ex) 
    { 
     // just bail 
     return 1; 
    } 
} 
+0

私は、WindowsではCreateFile()がロックをブロックしないと思った? – bdonlan

+0

あなたの権利のように見えるので、私は答えを編集します。 –

-1

は、単にシステムが

+0

詳しいことはありますか?おそらくリンクか例? –

関連する問題