我正在寻找一种在非托管 c ++中创建程序的方法,该方法等待文件解锁(因为它已不再使用)并且执行某些操作。我没有找到如何做到这一点的运气,任何帮助将不胜感激!
更新:我可能已回答了我自己的问题,请参阅下文并告诉我您的想法......
更新:真正重要的是文件是可写的,如果它仍在使用中并不重要。
答案 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 :(得分:1)
创建一个每5秒调用::CreateFile()的循环,直到成功为止。在dwShareMode参数中传递0,以确保没有其他进程打开文件。
答案 2 :(得分:0)
这是我的问题的一个可能的解决方案,有人看到这个问题吗?
#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..
}
再次感谢!
更新:将代码更改为更完整。
答案 3 :(得分: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中,您似乎必须轮询该文件。
视窗:
#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;
}
}
答案 4 :(得分:-1)
只需使用系统锁定文件通知