Вверх ↑
Этот топик читают: Гость
Ответов: 3851
Рейтинг: 159
#1: 2013-08-29 22:10:54 ЛС | профиль | цитата
code_31686.txt

1. DirectoryChanges выдаёт все результаты, если количество тестовых дисковых операций не более 28.
2. Если их меньше 29, то выделяется исключение из общей картины - "file_9.tst$".

Только у меня так?

P.S.: HiAsm 4.185; FPC/D4; XP-SP3
------------ Дoбавленo в 22.10:

Сегодня опять то же самое..

карма: 0
начавший
1
файлы: 1code_31686.txt [1.9KB] [649]
Голосовали:foksov
Разработчик
Ответов: 26151
Рейтинг: 2127
#2: 2013-08-30 01:35:31 ЛС | профиль | цитата
Да, есть такое, но не понятно почему ???

Надо попробовать не создавать и удалять файлы в цикле, а сделать небольшую задержку перед каждой операцией и посмотреть, те не использовать For, а применить счетчик с условием
карма: 22

0
Ответов: 4630
Рейтинг: 749
#3: 2013-08-30 14:04:23 ЛС | профиль | цитата
Это поведение зависит от длины имени файла. Как раз от перехода из 9 к 10 длина увеличивается. То же и даже больше можно увидеть при изменении длины имени в FormatStr. Выглядит, будто где-то при считывании/записывании строки неправильно определяется её длина и в конце остается мусорный символ.

------------ Дoбавленo в 14.04:
MSDN-FILE_NOTIFY_INFORMATION писал(а):

FileName
A variable-length field that contains the file name relative to the directory handle. The file name is in the Unicode character format and is not null-terminated.

Получилось примерно так:

#pas
procedure THiDirectoryChanges.HandleEvent;
var FileNotifyInfo : PFileNotifyInformation;
InfoCallBack : TInfoCallBack;
Offset : Longint;
WStr: string;
begin
Pointer(FileNotifyInfo) := @FWatchBuf[0];
repeat
Offset:=FileNotifyInfo^.NextEntryOffset;
InfoCallBack.FAction := FileNotifyInfo^.Action;
InfoCallBack.FDrive := FName;
SetLength(WStr, FileNotifyInfo.FileNameLength+1); // На 1 больше, так как должна оканчиваться двумя #0
WStr[FileNotifyInfo.FileNameLength + 1] := #0; // В конце получается #0#0
Move(FileNotifyInfo^.FileName[0], WStr[1], FileNotifyInfo.FileNameLength);
WStr := Trim(WideCharLenToString(@WStr[1], FileNotifyInfo.FileNameLength));
InfoCallBack.FNewFileName := WStr;
case FileNotifyInfo^.Action of
FILE_ACTION_RENAMED_OLD_NAME: FOldFileName := WStr;
FILE_ACTION_RENAMED_NEW_NAME: InfoCallBack.FOldFileName := FOldFileName;
end;
FInfoCallBack(InfoCallBack, sTag);
PChar(FileNotifyInfo) := PChar(FileNotifyInfo) + Offset;
until (Offset=0) or WFS.Terminated or (WFS = nil);
end;
У меня на Windows 2000 что в оригинале, что здесь при нажатии на 36 (а точнее, при некоторых длинах файлов) выдается только первое имя и пустое второе, дальше всё останавливается.
карма: 26

1
Голосовали:nesco
Разработчик
Ответов: 26151
Рейтинг: 2127
#4: 2013-08-30 15:09:13 ЛС | профиль | цитата
Netspirit писал(а):
Получилось примерно так:

Вроде нормально работает.
Netspirit писал(а):
У меня на Windows 2000 что в оригинале, что здесь при нажатии на 36 (а точнее, при некоторых длинах файлов) выдается только первое имя и пустое второе, дальше всё останавливается.

У меня так же
карма: 22

0
Ответов: 4630
Рейтинг: 749
#5: 2013-08-30 15:24:28 ЛС | профиль | цитата
Причина второго - похоже, недостаточный размер буфера, чтобы вместить все произошедшие изменения. Если уменьшить длину имени файла - 36 срабатывает.
карма: 26

0
Разработчик
Ответов: 26151
Рейтинг: 2127
#6: 2013-08-31 13:54:00 ЛС | профиль | цитата
Andrey, кстати, поток в схеме не нужен, внутри компонента уже и так создается поток на мониторинг
карма: 22

0
Ответов: 3851
Рейтинг: 159
#7: 2013-08-31 15:04:57 ЛС | профиль | цитата

nesco писал(а):
сделать небольшую задержку
code_31710.txt ага - проблема исчезла, получается - она не зависит
Netspirit писал(а):
от длины имени файла

а при "штатных" скоростях - как оно обычно происходит в системе, он просто "не успевает": code_31711.txt ..
карма: 0
начавший
0
файлы: 2code_31710.txt [1.6KB] [566], code_31711.txt [1.8KB] [608]
Разработчик
Ответов: 26151
Рейтинг: 2127
#8: 2013-08-31 15:54:30 ЛС | профиль | цитата
Andrey писал(а):
ага - проблема исчезла

Лучше обнови компонент и попробуй старую схему, но без потока
карма: 22

0
Ответов: 4630
Рейтинг: 749
#9: 2013-08-31 18:35:01 ЛС | профиль | цитата
Никто не замечал рантайм-эррор с этой поправкой при нажатии на 35 (зависит, из какого каталога запускать программу)?
Нужно поэкспериментировать. Кажется функция WideCharLenToString требует длину строки в символах, а не в байтах и плюет на нули в конце. А раз так, может ещё раз поправить вот так:


#pas
procedure THiDirectoryChanges.HandleEvent;
var FileNotifyInfo : PFileNotifyInformation;
InfoCallBack : TInfoCallBack;
Offset : Longint;
Str: string;
begin
Pointer(FileNotifyInfo) := @FWatchBuf[0];
repeat
Offset:=FileNotifyInfo^.NextEntryOffset;
InfoCallBack.FAction := FileNotifyInfo^.Action;
InfoCallBack.FDrive := FName;
Str := Trim(WideCharLenToString(@(FileNotifyInfo^.FileName[0]), FileNotifyInfo.FileNameLength div 2));
InfoCallBack.FNewFileName := Str;
case FileNotifyInfo^.Action of
FILE_ACTION_RENAMED_OLD_NAME: FOldFileName := Str;
FILE_ACTION_RENAMED_NEW_NAME: InfoCallBack.FOldFileName := FOldFileName;
end;
FInfoCallBack(InfoCallBack, sTag);
PChar(FileNotifyInfo) := PChar(FileNotifyInfo) + Offset;
until (Offset=0) or WFS.Terminated or (WFS = nil);
end;
карма: 26

0
Разработчик
Ответов: 26151
Рейтинг: 2127
#10: 2013-08-31 19:06:38 ЛС | профиль | цитата
Netspirit писал(а):
А раз так, может ещё раз поправить вот так:

Поправил
карма: 22

0
Ответов: 3851
Рейтинг: 159
#11: 2013-08-31 22:06:27 ЛС | профиль | цитата

обновил DirectoryChanges:
~ в старой (code_31686.txt) схеме, но без потока "35" - работает, "36" - не работает, затыкается после первых двух строчек.
~ тоже самое в реальной жизни (code_31711.txt) - по прежнему "не успевает"

карма: 0
начавший
0
Разработчик
Ответов: 26151
Рейтинг: 2127
#12: 2013-08-31 22:28:21 ЛС | профиль | цитата
Andrey писал(а):
тоже самое в реальной жизни (code_31711.txt) - по прежнему "не успевает"

У меня работает эта схема нормально с задержкой в 10
Andrey писал(а):
"36" - не работает, затыкается после первых двух строчек.

Написал же Netspirit предположение
Netspirit писал(а):
Причина второго - похоже, недостаточный размер буфера, чтобы вместить все произошедшие изменения. Если уменьшить длину имени файла - 36 срабатывает.

карма: 22

0
Ответов: 3851
Рейтинг: 159
#13: 2013-08-31 23:00:18 ЛС | профиль | цитата
В code_31711.txt, у меня результат такой: code_31713.txt, если у кого другой, покажите плиз..
карма: 0
начавший
0
файлы: 1code_31713.txt [2.8KB] [737]
Разработчик
Ответов: 26151
Рейтинг: 2127
#14: 2013-08-31 23:17:45 ЛС | профиль | цитата
Andrey писал(а):
если у кого другой, покажите плиз

У меня срабатывает вот так

result_10101.png
но не с первого раза
карма: 22

0
файлы: 1result_10101.png [35.7KB] [554]
Ответов: 4630
Рейтинг: 749
#15: 2013-09-01 12:16:42 ЛС | профиль | цитата
Если конкретная схема не дает достаточно результатов, можно для себя увеличить буфер здесь:
FWatchBuf : array[0..64*1024] of Byte;

карма: 26

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)