С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.52/25: Рейтинг темы: голосов - 25, средняя оценка - 4.52
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177

Мониторинг директории и копирование только новых файлов

09.06.2016, 19:15. Показов 5171. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет! Подскажите как реализовать следующую затею. Есть директория, в которой периодически появляются (добавляются) различные файлы. Необходимо по расписанию проверять появились ли в этой директории новые файлы (помимо скопированных ранее) и если таковые имеются скопировать их в заранее оговоренную директорию.
Нашел, что необходимо использовать функцию ReadDirectoryChangesW, либо присваивать скопированным ранее файлам некий атрибут (например faTemporary), который в дальнейшем проверять.
Нет ли у кого случаем готового решения подобной задачи или примера подобного кода?
Заранее спасибо!

Добавлено через 2 часа 2 минуты
Из множества примеров собрал следующее.
C++
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
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
 
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
class SpyThread : public TThread
{
    AnsiString stringToAdd;
    void __fastcall addString();
public:
virtual  void __fastcall Execute(void);
};
SpyThread *spy;    
 
void __fastcall SpyThread::Execute()
{
  AnsiString dir = "D:\\test";
HANDLE hdir = CreateFileA(dir.c_str(),
              FILE_LIST_DIRECTORY,
              FILE_SHARE_READ|FILE_SHARE_WRITE,
              NULL,
              OPEN_EXISTING,
              FILE_FLAG_BACKUP_SEMANTICS,
              NULL);
FILE_NOTIFY_INFORMATION Buffer[1024];
DWORD BytesReturned;
while ( !Terminated ) {
 
int ret = ReadDirectoryChangesW(
        hdir,
        &Buffer,
        sizeof(Buffer),
        True,
        FILE_NOTIFY_CHANGE_SECURITY|
        FILE_NOTIFY_CHANGE_SIZE|
        FILE_NOTIFY_CHANGE_ATTRIBUTES|
        FILE_NOTIFY_CHANGE_DIR_NAME|
        FILE_NOTIFY_CHANGE_FILE_NAME,
        &BytesReturned,
        NULL,
        NULL
        );
AnsiString name = Buffer[0].FileName;
switch(Buffer[0].Action)
  {
   case FILE_ACTION_ADDED:
   stringToAdd= "Файл добавлен"+ name;
    Synchronize( addString );
    break;
   case FILE_ACTION_REMOVED:
   stringToAdd= "Файл удален"+ name;
    Synchronize( addString );
    break;
   case FILE_ACTION_MODIFIED:
   stringToAdd= "Файл изменен"+ name;
   Synchronize( addString );
    break;
  }
  break;
}
 CloseHandle(hdir);       //перед выходом из потока закрыть объект-событие
 delete [] Buffer;
 
}
 
void __fastcall SpyThread::addString() {
    Form1->Memo2->Lines->Add( stringToAdd );
}
Однако добиться вывода в Memo появляющихся\удаляемых\модифицируемых файлов не удалось. Где моя ошибка?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.06.2016, 19:15
Ответы с готовыми решениями:

Копирование с заменой только новых файлов
Здравствуйте. Подскажите, пожалуйста, как можно скопировать файлы на носитель, заменяя при этом их только на более новые. Заранее спасибо. ...

Robocopy GUI: копирование только новых файлов
Помогите разобраться с Robocopy GUI.Какие команды лучше прописать. Нужно сделать копию папки с сервака куда падают бекапы с базы в архиве....

Копирование только новых и модифицированных файлов с сохранением структуры каталогов
драссти бьюсь об .BAT второй день цель - собрать батник с целью копирования большого количества подкаталогов и файлов из сетевого диска...

12
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
09.06.2016, 22:33
Лучший ответ Сообщение было отмечено gunslinger как решение

Решение

У меня проект Юникодный, собирал на XE2, вот этот код:
C++
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
void __fastcall SpyThread::Execute()
{
    String dir = "D:\\test";
    HANDLE hdir = CreateFile(dir.c_str(), FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    TCHAR Buffer[1024 * 128];
    DWORD BytesReturned;
    while (!Terminated)
    {
        while (ReadDirectoryChangesW(hdir, &Buffer, sizeof(Buffer), True,
            FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_SIZE |
            FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_DIR_NAME |
            FILE_NOTIFY_CHANGE_FILE_NAME, &BytesReturned, NULL, NULL))
        {
            DWORD dwOffset = 0;
            FILE_NOTIFY_INFORMATION* pInfo = NULL;
            do
            {
                pInfo = (FILE_NOTIFY_INFORMATION*)&Buffer[dwOffset];
                switch (pInfo->Action)
                {
                case FILE_ACTION_ADDED:
                    stringToAdd = L"Файл добавлен ";
                    break;
                case FILE_ACTION_REMOVED:
                    stringToAdd = L"Файл удален ";
                    break;
                case FILE_ACTION_MODIFIED:
                    stringToAdd = L"Файл изменен ";
                    break;
                }
 
                TCHAR szFileName[MAX_PATH] = {0};
                lstrcpynW(szFileName, pInfo->FileName, pInfo->FileNameLength / 2 + 1);
 
                stringToAdd += szFileName;
                Synchronize(addString);
                dwOffset += pInfo->NextEntryOffset;
            }
            while (pInfo->NextEntryOffset != 0);
        }
    }
    CloseHandle(hdir); // перед выходом из потока закрыть объект-событие
    delete[]Buffer;
 
}
прекрасно отрабатывает. Удаление/добавление/изменение файлов ловит прекрасно.
3
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
10.06.2016, 23:07  [ТС]
А можно полностью код Вашего проекта? Никак не выходит получить желаемое =(
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
10.06.2016, 23:46
Вот полностью код, который относится к слежению (я просто добавлял его к другому проекту, а не создавал проект с нуля) :
C++
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
class SpyThread : public TThread
{
    // Ansi
    String stringToAdd;
 
    void __fastcall addString();
 
public:
    virtual void __fastcall Execute(void);
};
 
SpyThread *spy;
 
void __fastcall SpyThread::Execute()
{
    String dir = "D:\\test";
    HANDLE hdir = CreateFile(dir.c_str(), FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    TCHAR Buffer[1024 * 128];
    DWORD BytesReturned;
    while (!Terminated)
    {
        while (ReadDirectoryChangesW(hdir, &Buffer, sizeof(Buffer), True,
            FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_SIZE |
            FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_DIR_NAME |
            FILE_NOTIFY_CHANGE_FILE_NAME, &BytesReturned, NULL, NULL))
        {
            DWORD dwOffset = 0;
            FILE_NOTIFY_INFORMATION* pInfo = NULL;
            do
            {
                pInfo = (FILE_NOTIFY_INFORMATION*)&Buffer[dwOffset];
                switch (pInfo->Action)
                {
                case FILE_ACTION_ADDED:
                    stringToAdd = L"Файл добавлен ";
                    break;
                case FILE_ACTION_REMOVED:
                    stringToAdd = L"Файл удален ";
                    break;
                case FILE_ACTION_MODIFIED:
                    stringToAdd = L"Файл изменен ";
                    break;
                }
 
                TCHAR szFileName[MAX_PATH] =
                {0};
                lstrcpynW(szFileName, pInfo->FileName,
                    pInfo->FileNameLength / 2 + 1);
 
                stringToAdd += szFileName;
                Synchronize(addString);
                dwOffset += pInfo->NextEntryOffset;
            }
            while (pInfo->NextEntryOffset != 0);
        }
    }
    CloseHandle(hdir); // перед выходом из потока закрыть объект-событие
    delete[]Buffer;
 
}
 
void __fastcall SpyThread::addString()
{
    Form1->Memo2->Lines->Add(stringToAdd);
}
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    spy = new SpyThread();
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    spy->Terminate();
}
Цитата Сообщение от rozalski Посмотреть сообщение
Никак не выходит получить желаемое =(
Что не выходит? Код не работает, или что?
1
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
12.06.2016, 13:15  [ТС]
Спасибо, вроде разобрался!

Добавлено через 16 часов 36 минут
В продолжение темы разбирательства с потоками.
Пытаюсь создать несколько потоков для слежения за директориями.
C++
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <FileCtrl.hpp>
#pragma hdrstop
 
#include "Unit1.h"
typedef UnicodeString US;
 
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
class SpyThread : public TThread
{
    String stringToAdd;
 
    void __fastcall addString();
 
public:
    virtual void __fastcall Execute(void);
};
        int size = 2; 
    SpyThread* *ArrayThread= new SpyThread* [size]; // массив указателей на потоки из 3 элементов (3 Edit)
void __fastcall SpyThread::Execute()
{
    String dir = "D:\\test"; // тут как-то надо использовать 3 директории введенные в Edit'ы и обрабатывать их в разных потоках????????
    HANDLE hdir = CreateFile(dir.c_str(), FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    TCHAR Buffer[1024 * 128];
    DWORD BytesReturned;
    while (!Terminated)
    {
        while (ReadDirectoryChangesW(hdir, &Buffer, sizeof(Buffer), True,
            FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_SIZE |
            FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_DIR_NAME |
            FILE_NOTIFY_CHANGE_FILE_NAME, &BytesReturned, NULL, NULL))
        {
            DWORD dwOffset = 0;
            FILE_NOTIFY_INFORMATION* pInfo = NULL;
            do
            {
                pInfo = (FILE_NOTIFY_INFORMATION*)&Buffer[dwOffset];
                switch (pInfo->Action)
                {
                case FILE_ACTION_ADDED:
                    stringToAdd = L"Файл добавлен ";
                    break;
                case FILE_ACTION_REMOVED:
                    stringToAdd = L"Файл удален ";
                    break;
                case FILE_ACTION_MODIFIED:
                    stringToAdd = L"Файл изменен ";
                    break;
                }
 
                TCHAR szFileName[MAX_PATH] =
                {0};
                lstrcpynW(szFileName, pInfo->FileName,
                    pInfo->FileNameLength / 2 + 1);
 
                stringToAdd += szFileName;
                Synchronize(addString);
                dwOffset += pInfo->NextEntryOffset;
            }
            while (pInfo->NextEntryOffset != 0);
        }
    }
    CloseHandle(hdir); // перед выходом из потока закрыть объект-событие
    delete[]Buffer;
}
 
void __fastcall SpyThread::addString()
{
    Form1->RichEdit1->Lines->Add(stringToAdd);
}
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    for(int i=0; i<=size; i++)
    ArrayThread[i] = new SpyThread(); // создание объектов-потоков
}
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 
    for(int i=0; i<=size; i++)
    ArrayThread[i] -> Terminate();
}
//---------------------------------------------------------------------------
US Path;
int count;
US SelectDir(){
TSearchRec sr;
    if(SelectDirectory("Выбери директорию!","",Path))
    {
        Path=Path+"";
    }
    else
    return Path;
    Form1->RichEdit1->Lines->Add("Выбрана директория: ""+Path+""");
    SendMessage(Form1->RichEdit1->Handle, WM_VSCROLL, MAKEWPARAM(SB_BOTTOM,0), 0); // прокрутка в самый низ
    return Path;
    }
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
 
    Edit1->Text=SelectDir();
    }
 
void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
Edit2->Text=SelectDir();
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
Edit3->Text=SelectDir();
}
//---------------------------------------------------------------------------
Создаю массив указателей на потоки из 3 элементов (использую 3 Edit'а в которые введены разные директории), по нажатию на Кнопку1 создаю 3 объекта-потока...
Что делать дальше не знаю =(
Хочу получить обработку каждой из директорий введенных в вышеуказанные Edit'ы в разных потоках, в правильном ли я двигаюсь направлении? Как далее реализовать задуманное?
Заранее спасибо!
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
12.06.2016, 14:58
Цитата Сообщение от rozalski Посмотреть сообщение
C++
1
for(int i=0; i<=size; i++)
Не <=, а строго меньше, раз индексация с 0 - значит, до size-1.

Ну и потом, я бы перед запуском потоков заставил пользователя заполнить все Edit-ы, и потом передавал бы путь к отслеживаемой папке как параметр потока. То есть, как-то:

C++
1
2
3
4
5
__fastcall SpyThread::SpyThread(String APath)
    : TThread(true) // создает "замороженный" поток
{
    FPath = APath; // String FPath - поле класса SpyThread
}
, в Execute использовать этот самый FPath вместо строго заданной папки, а инициализировал бы - вот так:

C++
1
2
3
4
5
6
7
// ...
    for(int i=0; i<size; i++)
    {
        ArrayThread[i] = new SpyThread(static_cast<TEdit*>(FindComponent("Edit" + IntToStr(i + 1)))->Text);
        ArrayThread[i]->Start(); // или Resume() для старых версий компилятора
    }
// ...
Ну, или каким-то образом затолкать ссылки на Edit-ы в массив, чтобы можно было в цикле к ним обратиться.
1
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
12.06.2016, 15:40  [ТС]
Сложно как-то с потоками у меня идет =) Ни черта не понял =)

Добавлено через 25 минут
Цитата Сообщение от volvo Посмотреть сообщение
Не <=, а строго меньше, раз индексация с 0 - значит, до size-1.
Переменная size у меня 2, поэтому <= (0,1,2 - как раз 3 элемента), тут все верно.
Благодаря Вашим советам получилось следующее:

C++
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <FileCtrl.hpp>
#pragma hdrstop
 
#include "Unit1.h"
typedef UnicodeString US;
 
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
class SpyThread : public TThread
{
    String stringToAdd, FPath;
    void __fastcall addString();
public:
    virtual void __fastcall Execute(void);
    __fastcall SpyThread::SpyThread(String APath)
    : TThread(true) // создает "замороженный" поток
{
    FPath = APath; // String FPath - поле класса SpyThread
}
};
int size = 2;
    SpyThread* *ArrayThread= new SpyThread* [size];
 
void __fastcall SpyThread::Execute()
{
    String dir = FPath;
    HANDLE hdir = CreateFile(dir.c_str(), FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    TCHAR Buffer[1024 * 128];
    DWORD BytesReturned;
    while (!Terminated)
    {
        while (ReadDirectoryChangesW(hdir, &Buffer, sizeof(Buffer), True,
            FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_SIZE |
            FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_DIR_NAME |
            FILE_NOTIFY_CHANGE_FILE_NAME, &BytesReturned, NULL, NULL))
        {
            DWORD dwOffset = 0;
            FILE_NOTIFY_INFORMATION* pInfo = NULL;
            do
            {
                pInfo = (FILE_NOTIFY_INFORMATION*)&Buffer[dwOffset];
                switch (pInfo->Action)
                {
                case FILE_ACTION_ADDED:
                    stringToAdd = L"Файл добавлен ";
                    break;
                case FILE_ACTION_REMOVED:
                    stringToAdd = L"Файл удален ";
                    break;
                case FILE_ACTION_MODIFIED:
                    stringToAdd = L"Файл изменен ";
                    break;
                }
 
                TCHAR szFileName[MAX_PATH] =
                {0};
                lstrcpynW(szFileName, pInfo->FileName,
                    pInfo->FileNameLength / 2 + 1);
 
                stringToAdd += szFileName;
                Synchronize(addString);
                dwOffset += pInfo->NextEntryOffset;
            }
            while (pInfo->NextEntryOffset != 0);
        }
    }
    CloseHandle(hdir); // перед выходом из потока закрыть объект-событие
    delete[]Buffer;
 
}
 
void __fastcall SpyThread::addString()
{
    Form1->RichEdit1->Lines->Add(stringToAdd);
}
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  for(int i=0; i<=size; i++)
    {
        ArrayThread[i] = new SpyThread(static_cast<TEdit*>(FindComponent("Edit" + IntToStr(i + 1)))->Text);
        ArrayThread[i]->Start(); // или Resume() для старых версий компилятора
    }
}
 
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 
 
    for(int i=0; i<=size; i++)
    ArrayThread[i] -> Terminate();
 
}
//---------------------------------------------------------------------------
US Path;
int count;
US SelectDir(){
TSearchRec sr;
    if(SelectDirectory("Выбери директорию!","",Path))
    {
        Path=Path+"";
    }
    else
    return Path;
    Form1->RichEdit1->Lines->Add("Выбрана директория: ""+Path+""");
    SendMessage(Form1->RichEdit1->Handle, WM_VSCROLL, MAKEWPARAM(SB_BOTTOM,0), 0); // прокрутка в самый низ
    return Path;
    }
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
 
    Edit1->Text=SelectDir();
 
    }
 
 
//---------------------------------------------------------------------------
 
void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
Edit2->Text=SelectDir();
 
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
Edit3->Text=SelectDir();
 
}
Все запустилось, вроде даже как 3 потока работает (как кстати проверить подскажите?), но в РичЕдит выводит сразу 3 результата, т.е. если в одну из трех директорий, подлежащих наблюдению, копировать новый файл в РичЕдит выводится:

Копируем в директорию № 1 файл Unit1.dfm, получаем:
Bash
1
2
3
Файл добавлен Unit1.dfm
Файл изменен Unit1.dfm
Файл изменен Unit1.dfm
Копируем в директорию № 2 файл Unit2.cpp, получаем:
Bash
1
2
3
Файл добавлен Unit2.cpp
Файл изменен Unit2.cpp
Файл изменен Unit2.cpp
Копируем в директорию № 3 файл Project1.cpp, получаем:
Bash
1
2
3
Файл добавлен Project1.cpp
Файл изменен Project1.cpp
Файл изменен Project1.cpp
Я предполагаю, что так быть не должно....
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
12.06.2016, 15:45
Лучший ответ Сообщение было отмечено rozalski как решение

Решение

Чего не понятно?
C++
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
class SpyThread : public TThread
{
    String FPath;
    String stringToAdd;
 
    void __fastcall addString();
 
public:
    __fastcall SpyThread(String APath) : TThread(true)
    {
        FPath = APath;
    }
    virtual void __fastcall Execute(void);
};
 
SpyThread *spy;
 
void __fastcall SpyThread::Execute()
{
    // String dir = "D:\\test";
    HANDLE hdir = CreateFile(FPath.c_str(), FILE_LIST_DIRECTORY,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    TCHAR Buffer[1024 * 128];
    DWORD BytesReturned;
    while (!Terminated)
    {
        while (ReadDirectoryChangesW(hdir, &Buffer, sizeof(Buffer), True,
            FILE_NOTIFY_CHANGE_SECURITY | FILE_NOTIFY_CHANGE_SIZE |
            FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_DIR_NAME |
            FILE_NOTIFY_CHANGE_FILE_NAME, &BytesReturned, NULL, NULL))
        {
            DWORD dwOffset = 0;
            FILE_NOTIFY_INFORMATION* pInfo = NULL;
            do
            {
                pInfo = (FILE_NOTIFY_INFORMATION*)&Buffer[dwOffset];
                switch (pInfo->Action)
                {
                case FILE_ACTION_ADDED:
                    stringToAdd = L"Файл добавлен ";
                    break;
                case FILE_ACTION_REMOVED:
                    stringToAdd = L"Файл удален ";
                    break;
                case FILE_ACTION_MODIFIED:
                    stringToAdd = L"Файл изменен ";
                    break;
                }
 
                TCHAR szFileName[MAX_PATH] = {0};
                lstrcpynW(szFileName, pInfo->FileName, pInfo->FileNameLength / 2 + 1);
 
                stringToAdd += FPath + "\\" + szFileName;
                Synchronize(addString);
                dwOffset += pInfo->NextEntryOffset;
            }
            while (pInfo->NextEntryOffset != 0);
        }
    }
    CloseHandle(hdir); // перед выходом из потока закрыть объект-событие
    delete[]Buffer;
}
 
void __fastcall SpyThread::addString()
{
    Form1->Memo2->Lines->Add(stringToAdd);
}
 
const int threadsSize = 2;
SpyThread *ArrayThread[threadsSize];
 
void __fastcall TForm1::Button21Click(TObject *Sender)
{
    //
    for(int i = 0; i < threadsSize; i++)
    {
        ArrayThread[i] = new SpyThread(static_cast<TEdit*>(FindComponent("Edit" + IntToStr(i + 1)))->Text);
        ArrayThread[i]->Start();
    }
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::Button22Click(TObject *Sender)
{
    for(int i = 0; i < threadsSize; i++)
    {
        ArrayThread[i]->Terminate();
    }
}
, вот результат:
Миниатюры
Мониторинг директории и копирование только новых файлов  
2
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
12.06.2016, 15:49  [ТС]
Да, на удаление у меня тоже нормально одной строкой выводится, а вот если копирую в эти директории файлы, то получается как я выше указал...
Если создаю в директории файл, то тоже все норм... проблема только с копированием получается.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
12.06.2016, 15:52
Цитата Сообщение от rozalski Посмотреть сообщение
Я предполагаю, что так быть не должно....
Файл в папку был добавлен? Был. Это первое сообщение. Дата создания файла изменилась? Изменилась. Это второе сообщение. Время последнего обращения к файлу изменилось? Изменилось. Это третье. Что не так?
1
11 / 11 / 9
Регистрация: 26.08.2011
Сообщений: 177
12.06.2016, 16:04  [ТС]
Да, все верно, что-то это я туплю =) Спасибо за помощь!
0
1 / 1 / 1
Регистрация: 07.04.2016
Сообщений: 243
07.02.2018, 09:18
rozalski, Доброго времени суток. Скажите, остался у вас проект или нет? Очень интересно, хотелось бы с ним поработать
0
 Аватар для POJIBOX
2 / 2 / 0
Регистрация: 03.06.2018
Сообщений: 163
30.01.2024, 17:44
При большой интенсивности записи файлов пропускает с 500 файлов обнаружено только 479...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.01.2024, 17:44
Помогаю со студенческими работами здесь

Мониторинг файлов в сетевой директории
Здравствуйте. Подскажите, что не так. Есть замечательный инструмент FileSystemWatcher Все отлично работает, НО только в локали. Т.е. если...

Мониторинг ftp на наличие новых файлов
День добрый! Подскажите, есть ftp сервер (не мой) с множеством папок и файлов. Новые файлы появляются раза 2 в неделю. Но их использовать...

Мониторинг новых файлов сетевом окружении
Здраствуйте. Появилась необходимость мониторить несколько папок на разных ПК в сетевом окружении на наличие только что созданных файлов. ...

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

Мониторинг папок на появление в них новых файлов
Здравствуйте! не программирую уже 8 лет, но так получилось что для работы надо написать простенькую программу Суть такая, есть 2 папки в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru