powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Кто поможет со ошибкой в ReadDirectoryChangesW?
5 сообщений из 5, страница 1 из 1
Кто поможет со ошибкой в ReadDirectoryChangesW?
    #39397271
gera3323
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
#include <iostream>
#include <conio.h>

#include <vector>

using std::vector;
using std::cout;
using std::cin;
using std::endl;

#define pause() (_getch(),0)

#include <Windows.h>

DWORD dwFilterNotify = FILE_NOTIFY_CHANGE_FILE_NAME;
/*
            FILE_NOTIFY_CHANGE_FILE_NAME   | 
                   FILE_NOTIFY_CHANGE_DIR_NAME    | 
             FILE_NOTIFY_CHANGE_ATTRIBUTES  | 
             FILE_NOTIFY_CHANGE_SIZE        | 
             FILE_NOTIFY_CHANGE_LAST_WRITE  | 
             FILE_NOTIFY_CHANGE_LAST_ACCESS | 
             FILE_NOTIFY_CHANGE_CREATION    | 
             FILE_NOTIFY_CHANGE_SECURITY; 
*/

int error()
{
 DWORD _error = ::GetLastError();
 cout<<"Error code: "<<_error<<endl;
 return _error;
}

const int size_fni = 100 * sizeof(FILE_NOTIFY_INFORMATION);

struct SDir 
{
 OVERLAPPED Over;
 BYTE *pBuffer;

 SDir() {
  pBuffer = new BYTE[size_fni + 1];
 }

~SDir() {
  delete []pBuffer;
 }
};

HANDLE CreateIoCompletionPort(DWORD dwNumberOfConcurrentThreads = 1) {
 return ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, dwNumberOfConcurrentThreads); 
}

BOOL AssignIoCompletionPort(HANDLE hDirectory, HANDLE hExistingCompletionPort, ULONG_PTR CompletionKey) {
 return 
   (::CreateIoCompletionPort(hDirectory, hExistingCompletionPort, CompletionKey, 0) != NULL);
}

HANDLE AssignDirectory(LPTSTR lpDirectory) {
 return ::CreateFile(lpDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, 
   NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);   
}

LPCSTR ExplainAction( DWORD dwAction )
{
  switch (dwAction)
  {
  case FILE_ACTION_ADDED            :
    return "Added";
  case FILE_ACTION_REMOVED          :
    return "Deleted";
  case FILE_ACTION_MODIFIED         :
    return "Modified";
  case FILE_ACTION_RENAMED_OLD_NAME :
    return "Renamed From";
  case FILE_ACTION_RENAMED_NEW_NAME :
    return "Renamed To";
  default:
    return "BAD DATA";
  }
}

DWORD __stdcall Thread(LPVOID lpParam)
{
  DWORD dwNumberOfBytesTransferred;
  
  HANDLE hDevice = nullptr;
  SDir* pDir = nullptr;

  DWORD dwBytesReturned = 0;

  for(;;)
  {
    BOOL _error = ::GetQueuedCompletionStatus(static_cast<HANDLE>(lpParam), &dwNumberOfBytesTransferred, (ULONG_PTR*)&hDevice, (OVERLAPPED**)&pDir, INFINITE);     

    if(!_error) {
       error();
    }

      FILE_NOTIFY_INFORMATION *pBuffer = (FILE_NOTIFY_INFORMATION*)pDir->pBuffer;

          char*pChar = new char[pBuffer->FileNameLength / 2+1];

      WideCharToMultiByte( CP_ACP, 0, 
                 pBuffer->FileName, 
                 pBuffer->FileNameLength, 
                 pChar,
                 pBuffer->FileNameLength / 2, 
                 NULL, NULL);

      pChar[ pBuffer->FileNameLength / 2 ] = 0;

      cout<<pChar<<' '<<ExplainAction(pBuffer->Action)<<endl;

      delete pChar;

      /*

    */

    memset((void*)&pDir->Over, 0, sizeof(OVERLAPPED));
    //memset((void*)pDir->pBuffer, 0, 100);

    

    _error = ::ReadDirectoryChangesW(
      hDevice, pDir->pBuffer, size_fni, FALSE, dwFilterNotify, &dwBytesReturned, &pDir->Over, 0 );   

    // parsing
    Sleep(1000);
    
  }

  return 0;
}

HANDLE CreateThread(HANDLE hIOCP)
{
 DWORD dwThreadId = 0;
 return ::CreateThread(NULL, 0, Thread, hIOCP, 0, &dwThreadId); 
}

int main()
{
  HANDLE hIOCP = CreateIoCompletionPort();

  DWORD dwBytesReturned = 0;

  SDir *pDir = new SDir;

  memset((void*)&pDir->Over, 0, sizeof(OVERLAPPED));

  if(!hIOCP) {
    return error();
  }

  HANDLE hThread = CreateThread(hIOCP);

  if(!hThread) {
    return error();
  }

  HANDLE hDirectory = nullptr;


  hDirectory = AssignDirectory(L"C:\\space\\1");

  if(!AssignIoCompletionPort(hDirectory, hIOCP, (ULONG_PTR)hDirectory))
  {
   return error();	
  }

  BOOL _error = ::ReadDirectoryChangesW(
    hDirectory, pDir->pBuffer, size_fni, FALSE, dwFilterNotify, &dwBytesReturned, &pDir->Over, 0 );    

  if(!_error)
  {
   return error();	
  }

  hDirectory = AssignDirectory(L"C:\\space\\2");

  if(!AssignIoCompletionPort(hDirectory, hIOCP, (ULONG_PTR)hDirectory))
  {
   return error();	
  }

  //cout<< hDirectory << endl;

  _error = ::ReadDirectoryChangesW(
    hDirectory, pDir->pBuffer, size_fni, FALSE, dwFilterNotify, &dwBytesReturned, &pDir->Over, 0 );   

  
  WaitForSingleObject(hThread, INFINITE);



  return pause();
}



Проблема в следующем:
наблюдение я ввиду за директорией "C:\\space\\1"

1. Если я кидаю в нее файлы: 29-00014.IN, 29-00014.txt, 29-00015.IN, 29-00015.txt, то 1 или 2 файла не фиксируются функцией( не выводятся на консоль). С удалением тоже самое.
2. Иногда бывает когда я бросаю 4 файла в папу то вывод будет типа этого
"29-00014.txt" "29-00014.txt" "29-00014.txt" "29-00014.IN"

Вывод идет в Thread
...
Рейтинг: 0 / 0
Кто поможет со ошибкой в ReadDirectoryChangesW?
    #39397304
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И это естественно, поскольку ты выводишь только один файл из всего полученного пакета.

Сравни это с моим кодом (который работает):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
bool PrintBuf(char* buf)
{
      char* CurRec = buf;
      PFILE_NOTIFY_INFORMATION info;
      do
      {
        info = (PFILE_NOTIFY_INFORMATION)CurRec;
        switch (info->Action)
        {
        case FILE_ACTION_ADDED: printf("new file: "); break;
        case FILE_ACTION_REMOVED: printf("deleted file: "); break;
        case FILE_ACTION_MODIFIED: printf("modified file: "); break;
        case FILE_ACTION_RENAMED_OLD_NAME: printf("renamed from: "); break;
        case FILE_ACTION_RENAMED_NEW_NAME: printf("renamed into: "); break;
        default: printf("WTF %ld: ", info->Action);
        }
        WriteConsoleW(out, info->FileName, info->FileNameLength/sizeof(WCHAR), NULL, NULL);
        printf("\n");
        CurRec = CurRec + info->NextEntryOffset;
      }
      while (info->NextEntryOffset != 0);
      return true;
}
.........

    HANDLE f = CreateFile(TempDir,  // file name
		FILE_LIST_DIRECTORY|SYNCHRONIZE,                // access (read/write) mode
		FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,  // share mode
		NULL,                               // security descriptor
		OPEN_EXISTING,                      // how to create
		FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,         // file attributes
		NULL);                              // file with attributes to copy
    if (f == INVALID_HANDLE_VALUE)
    {
       printf("Could not open temporary directory %ld.\n", GetLastError());
       return 1;
    }
    char buffer[65535];
    DWORD ResultLength;
    do
    {
       OVERLAPPED o;
       o.hEvent = 0;
       if (ReadDirectoryChangesW(f, buffer, sizeof(buffer), FALSE,
			FILE_NOTIFY_CHANGE_FILE_NAME, &ResultLength, &o, NULL) == 0)
       {
           printf("ReadDirectoryChanges returned error %ld\n", GetLastError());
           return 1;
       }
       HANDLE events[] = { StopEvent, f };
       DWORD got = WaitForMultipleObjects(2, events, FALSE, INFINITE);
       switch (got)
       {
       case WAIT_OBJECT_0:
          {
             printf("Finishig, closing and going home...\n");
             if (CancelIo(f) == 0)
                printf("Canceling failed\n");
             if (CloseHandle(f) == 0)
                printf("Closing filed\n");
             return 0;
          }
       case WAIT_OBJECT_0 + 1: break;
       default:
          printf("WaitForSingleObject returned error %ld\n", GetLastError());
          return 1;
       }
       if (GetOverlappedResult(f, &o, &ResultLength, FALSE) == 0)
       {
          printf("GetOverlappedResult returned error %ld\n", GetLastError());
          return 1;
       }
       if (ResultLength == 0)
       {
         printf("------- not enough buffer ----------\n");
         continue;
       }
       else printf("--- file change packet with data length = %ld ---\n", ResultLength);
    }
    while (PrintBuf(buffer));


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кто поможет со ошибкой в ReadDirectoryChangesW?
    #39397719
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gera3323
Код: plaintext
1.
2.
3.
          char*pChar = new char[pBuffer->FileNameLength / 2+1];
      ...
      delete pChar;

Надо так:
Код: plaintext
1.
delete[] pChar;
...
Рейтинг: 0 / 0
Кто поможет со ошибкой в ReadDirectoryChangesW?
    #39398027
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пётр Седов, gera3323 ,

лучше вообще

Код: plaintext
1.
std::vector<char>(pBuffer->FileNameLength / 2+1);
...
Рейтинг: 0 / 0
Кто поможет со ошибкой в ReadDirectoryChangesW?
    #39398049
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivПётр Седов, gera3323,
лучше вообще ... std::string
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Кто поможет со ошибкой в ReadDirectoryChangesW?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]