0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ファイル操作関連のメモ(3点)

Posted at

1. 他のプロセスがやってるダウンロード始まった?終わった?

他のプロセスがおこなっている外部からのファイルダウンロード完了を、これで検知できるかなぁ。。。

(1) 特定のフォルダーにファイルが作成されたかどうか調べる

  char pdir[MAX_PATH]{};
  char cdir[MAX_PATH]{};

  strcpy(pdir, HomeFolderName);
  GetCurrentDirectory(MAX_PATH, cdir);

  HANDLE hdir=CreateFile(pdir, FILE_LIST_DIRECTORY,
                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL);
  WCHAR lpBuffer[MAX_PATH]{};
  DWORD  dwNotifyFilter=FILE_NOTIFY_CHANGE_FILE_NAME;
  HANDLE hEventF=CreateEvent(NULL, TRUE, FALSE, NULL);
  OVERLAPPED olp{}; olp.hEvent=hEventF;
  if(hdir!=INVALID_HANDLE_VALUE){
    ReadDirectoryChangesW(hdir, lpBuffer, MAX_PATH, TRUE, dwNotifyFilter, NULL, &olp, NULL);
  }
  
  for(;;){
      if(hdir!=INVALID_HANDLE_VALUE){
        if(WaitForSingleObject(hEventF, 0)!=WAIT_TIMEOUT){
          ResetEvent(hEventF);
          DWORD retsize=0;
          GetOverlappedResult(hdir, &olp, &retsize, FALSE);
          FILE_NOTIFY_INFORMATION *lpInfomation=(FILE_NOTIFY_INFORMATION *)&lpBuffer[0];
          if(lpInfomation!=NULL){
            if(lpInfomation->Action==FILE_ACTION_ADDED){
              char buf[MAX_PATH]{};
              WideCharToMultiByte(CP_ACP, 0, lpInfomation->FileName, -1, buf, MAX_PATH, NULL, NULL);
              printf("new file added '%s'", buf);
            }
            memset(lpBuffer, 0, MAX_PATH*sizeof(wchar_t));
          }
          ReadDirectoryChangesW(hdir, lpBuffer, MAX_PATH, TRUE, dwNotifyFilter, NULL, &olp, NULL);
        }
      }
      Sleep(10);
    }

(2) 他のプロセスがファイル作成を完了する(ハンドルを開放する)まで待つ

# include <RestartManager.h>
# pragma comment(lib, "Rstrtmgr.lib")
int EnumProcessFileOpened(char filenameA[])
{
  WCHAR filenameW[MAX_PATH];
  MultiByteToWideChar(CP_ACP, 0, filenameA, -1, filenameW, MAX_PATH);

  const int nfiles=1;
  LPCWSTR pszfiles[nfiles];
  pszfiles[0]=filenameW;

  int nproc=-1;
  DWORD dwError;
  DWORD dwSession;
  WCHAR szSessionKey[CCH_RM_SESSION_KEY+1]{};
  dwError=RmStartSession(&dwSession, 0, szSessionKey);
  if(dwError==ERROR_SUCCESS){
    dwError=RmRegisterResources(dwSession, nfiles, pszfiles, 0, NULL, 0, NULL);
    if(dwError==ERROR_SUCCESS){
      UINT nProcInfoNeeded=0;
      UINT nProcInfo=0;
      RM_PROCESS_INFO *rgpi=NULL;
      DWORD dwReason=RmRebootReasonNone;
      dwError=RmGetList(dwSession, &nProcInfoNeeded, &nProcInfo, rgpi, &dwReason);
      if(dwError==ERROR_MORE_DATA){
        printf("this file is opened by %d processes", nProcInfoNeeded);
        nproc=nProcInfoNeeded;
      }else if(dwError==ERROR_SUCCESS){
        printf("this file is opened by %d processes", nProcInfoNeeded);
      }else{
        nproc=-1;
      }
    }
    RmEndSession(dwSession);
  }
  return nproc;
}

2. 読み込みに時間かかってるから途中でキャンセル

読み込みスレッド

HANDLE hthread=INVALID_HANDLE_VALUE;
DWORD __stdcall ThreadProc(void *h)
{
  HANDLE *hfile=static_cast<HANDLE *>(h);
  unsigned char buffer[LARGE_SIZE];
  DWORD dwSize;
  ReadFile(*hfile, buffer, LARGE_SIZE, &dwSize, 0);
  return 0;
}

呼び出し側

  HANDLE hfile=CreateFile("c:\\Work\\test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  hthread=CreateThread(NULL, 0, ThreadProc, &hfile, 0, NULL);

...

  CancelIoEx(hfile, NULL);
  WaitForSingleObject(hthread, INFINITE);
  CloseFile(hfile);

3. 書き込んだけど全部キャンセル(トランザクションNTFSの利用)

  HANDLE htran=CreateTransaction(NULL, 0, TRANSACTION_DO_NOT_PROMOTE, 0, 0, 0, L"");

  HANDLE hfile=CreateFileTransacted("c:\\Work\\test1.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 
                                    FILE_ATTRIBUTE_NORMAL, NULL,
                                    htran, NULL, NULL);
  DWORD dwSize;
  WriteFile(hfile, "test", 4, &dwSize, NULL);
  CloseHandle(hfile);

  //  CommitTransaction(htran); //Commitする場合には、今までのファイル操作をアトミックに反映
  RollbackTransaction(htran);

  CloseHandle(htran);

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?