Текущий архив: 2008.10.19;
Скачать: CL | DM;
ВнизДля опытного глаза Найти похожие ветки
← →
Dennis I. Komarov © (2007-10-26 12:26) [40]> [39] Сергей М. © (26.10.07 11:44)
Но ведь не асинхронный.
← →
Сергей М. © (2007-10-26 12:32) [41]
> Dennis I. Komarov © (26.10.07 12:26) [40]
> Но ведь не асинхронный.
С чего ты так уверен ?
Да и какая разница, синхронный или асинхронный ?
Режим не имеет значения с т.з. твоих волнений насчет "потерь" .
← →
Dennis I. Komarov © (2007-10-26 13:34) [42]> С чего ты так уверен ?
Ибо обновление по F5 получаем. Я сомниваюсь, что все это время Explorer хранит эти изменения, и отображает их по команде.
А первоначальную информацию он как читает?
----------
lpNumberOfBytesTranferred - это VAR ? Он вообще имеет значение, ведь читаль lpBuf будем.
← →
Сергей М. © (2007-10-26 14:40) [43]
> Ибо обновление по F5 получаем
А у меня Explorer сам отслеживает изменения в показываемой им в тек.момент директории.
Что я делаю не так ?
> А первоначальную информацию он как читает?
А по барабану как он ее читает. Мы же об отслеживании изменений речь ведем)
> это VAR ?
Это Points to a 32-bit variable that receives the number of bytes that were actually transferred by a read or write operation
> Он вообще имеет значение
А нафига он тогда фигурирует в структуре, если он якобы не нужен ?
← →
Dennis I. Komarov © (2007-10-26 15:47) [44]> Это Points to a 32-bit variable that receives the number
> of bytes that were actually transferred by a read or write
> operation
Я F1 умею жать :) только не понял почему Points
Мой скромный перевод - это скока надо читать ин-фы из lpBuf. (разумеется не переменная)
← →
Сергей М. © (2007-10-26 15:51) [45]
> Dennis I. Komarov © (26.10.07 15:47) [44]
А, ты вон про что ..
Ну да, в дельфийской декларации этот параметр объявлен для передачи по ссылке, т.е. как var-параметр.
> Мой скромный перевод - это скока надо читать ин-фы из lpBuf.
> (разумеется не переменная)
Правильно перевел.
← →
Dennis I. Komarov © (2007-10-26 16:35) [46]Как понимаю, lpBuff заполняется пакетамя типа TFileNotifyInformation, в котором NextEntryOffset отвечает за существование следующего пакета. Отсюда и возник вопрос, нужен ли pNumberOfBytesTranferred вообще.
И как лучше сделать:
1.
...
if WaitFor...... do
begin
if ReadDir...
//далее разбираем lpBuf
end;
2.
if WaitFor...... do
begin
//тут разбираем lpBuf
if ReadDir...
end;
← →
Сергей М. © (2007-10-26 16:51) [47]if WaitFor...... and GetOverlappedResult(..) then
begin
if ReadDir...
//далее разбираем lpBuf
end;
← →
Dennis I. Komarov © (2007-10-29 13:52) [48]А как положено разбирать lpBuf? Ведь там может храниться несколько записей типа TFileNotifyInformation.
← →
Сергей М. © (2007-10-29 13:59) [49]
> как положено разбирать lpBuf?
В точном соответствии с офиц.описанием структуры FILE_NOTIFY_INFORMATION.
> Ведь там может храниться несколько записей типа
И что ?
← →
Dennis I. Komarov © (2007-10-29 17:10) [50]> [47] Сергей М. © (26.10.07 16:51)
> if WaitFor...... and GetOverlappedResult(..) then
> begin
> if ReadDir...
> //далее разбираем lpBuf
Если получаем информацию, о появлении нового файла, то отправляем на FTP, исли он отправился успешно, то удаляем его => получаем очередное изменение, а значит lpBuf изменен, т.е. все остальные информацонные записи - утеряны :(
Как быть?
> end;
← →
Сергей М. © (2007-10-30 08:18) [51]
> Как быть?
Ну как ?...
Конечно же скопировать содержимое lpBuf^ во временный буфер и разбирать уже этот временнный буфер, а не lpBuf^. Неужели это не очевидно ?
← →
Dennis I. Komarov © (2007-10-30 15:23) [52]
unit u_send;
interface
uses
Classes, Windows, SysUtils, StrUtils, DateUtils,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdFTP, IniFiles;
type
TThreadSend = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
implementation
uses
Main;
{ TThreadSend }
type
PFileNotifyInformation = ^TFileNotifyInformation;
TFileNotifyInformation = packed record
NextEntryOffset: DWORD;
Action: DWORD;
FileNameLength:DWORD;
FileName: WideChar;
end;
TTFileNotifyInformationArray = array[0..1000] of TFileNotifyInformation;
procedure TThreadSend.Execute;
var
i: Integer;
tBuf: TTFileNotifyInformationArray;
hDir, hDirChangeEvent: THandle;
lpBuf: Pointer;
lpOverlapped: POverlapped;
lpNumberOfBytesTansferred: Cardinal;
begin
{ Place thread code here }
FreeOnTerminate:=false;
hDirChangeEvent:=CreateEvent(nil, false, false, PChar("OnChangeDirecory"));
hDir := CreateFile ( "c:\test", GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);
if hDir <> INVALID_HANDLE_VALUE then begin
GetMem(lpBuf, 64*1024);
GetMem(lpOverlapped, SizeOf(lpOverlapped^));
try
ZeroMemory(lpBuf, 64*1024);
lpOverlapped^.hEvent:=hDirChangeEvent;
if ReadDirectoryChangesW(hDir, lpBuf, SizeOf(lpBuf), true, FILE_NOTIFY_CHANGE_FILE_NAME, nil, lpOverlapped, nil) then
while not Terminated do begin
if (WaitForSingleObject(hDirChangeEvent, 1000) = WAIT_OBJECT_0) and
(GetOverLappedResult(hDir, lpOverlapped^, lpNumberOfBytesTansferred, true)) then begin
//Копируем результаты в резервный буфер
tBuf:=TTFileNotifyInformationArray(lpBuf^);
while not ReadDirectoryChangesW(hDir, lpBuf, SizeOf(lpBuf), true, FILE_NOTIFY_CHANGE_FILE_NAME, nil, lpOverlapped, nil) do;
i:=0;
repeat
{
Разбераем tBuf[i]
Если появился новый => шмаляем, исли гуд то в архив
{}
Inc(i);
until tBuf[i].NextEntryOffset > 0
end;
end;
finally
FreeMem(lpBuf);
FreeMem(lpOverlapped);
CloseHandle(hDirChangeEvent);
CloseHandle(hDir);
end;
end;
end;
end.
Вот такой "безобразие". Как оно?
← →
Сергей М. © (2007-10-30 15:33) [53]Действительно безобразие)
> while not ReadDirectoryChangesW(hDir, lpBuf, SizeOf(lpBuf),
> true, FILE_NOTIFY_CHANGE_FILE_NAME, nil, lpOverlapped,
> nil) do;
Накой ляд тут этот цикл ?
> tBuf:=TTFileNotifyInformationArray(lpBuf^);
А это что такое ?
Как кореллирует sizeof(TTFileNotifyInformationArray) c 64*1024 и lpNumberOfBytesTansferred^ ?
← →
Dennis I. Komarov © (2007-10-30 15:50) [54]> Накой ляд тут этот цикл ?
Дабы если false, то пытался поставить запрос заново :)
> Как кореллирует sizeof(TTFileNotifyInformationArray) c 64*1024
> и lpNumberOfBytesTansferred^ ?
Откровенно говоря никак, но он веди не меньше получится. Я так понимаю, что остальные элементы массива просто пустыми остануться. А 1000 поставил из-за щедрости :)
Ок, понял. Меняем packed record на просто record
array [0..4095] of ....
← →
Сергей М. © (2007-10-30 16:11) [55]
> Дабы если false, то пытался поставить запрос заново
Малацца, что тут сказать)
А почему false - тебе по барабану.
Жди бесконечного цикла)
> А 1000 поставил из-за щедрости
От балды ты поставил, а не "из-за щедрости")
Программа, реализованная от балды, работать как положено никогда не будет.
У тебя есть lpNumberOfBytesTansferred^, у тебя есть связный список в lpBuf^, вот пробегись по этому списку и выдели памяти под врем.буфер ровно столько, сколько нужно, но не более lpNumberOfBytesTansferred^
← →
Dennis I. Komarov © (2007-10-30 16:47) [56]Почему
> lpNumberOfBytesTansferred^
?
GetOverLappedResult(hDir, lpOverlapped^, lpNumberOfBytesTansferred, true)
третьим параметром указатель кушать не хочет, хотя в справке LPDWORD
В функции хочет Cardinal а на Pointer ругается.
> От балды ты поставил, а не "из-за щедрости")
Неее, балда подумала, что этого более чем хватит!
A array [0..4095] of ... почему низя сделать? Получим такойже объем (64*1024 = SizeOf(TFileNotifyInformation)*4096). По идее все должно оказаться в массиве. С ним же удобнее работать. Ну и пусть памяти быдет выделено немного больше (65Kb Не так страшно)
← →
Сергей М. © (2007-10-30 16:55) [57]BytesTansferred: Cardinal;
..
GetOverLappedResult(... BytesTansferred ...)
> A array [0..4095] of ... почему низя сделать?
А почему не 100000 ? Почему не миллион ?
От балды оно и есть от балды, типа авось хватит)
А надо не "авось", а ровно столько, сколько возвращено операцией чтения.
← →
Dennis I. Komarov © (2007-10-30 17:08) [58]while not Terminated do begin
if (WaitForSingleObject(hDirChangeEvent, 1000) = WAIT_OBJECT_0) and
(GetOverLappedResult(hDir, lpOverlapped^, lpNumberOfBytesTansferred, true)) then begin
//Копируем результаты в резервный буфер
GetMem(tempBuf, lpNumberOfBytesTansferred);
try
tempBuf^:=???
if not ReadDirectoryChangesW(hDir, lpBuf, SizeOf(lpBuf), true, FILE_NOTIFY_CHANGE_FILE_NAME, nil, lpOverlapped, nil)
then ; //Тут все плохо, запрос не посавился смотреть GetLastError
finally
FreeMem(tempBuf);
end;
end;
end;
← →
Сергей М. © (2007-10-30 17:12) [59]CopyMemory(tempBuf, lpBuf, NumberOfBytesTansferred)
← →
Dennis I. Komarov © (2007-10-30 17:23) [60]А если к примеру в этом месте происходит событие (Появился/удалился новый файл), то вернувшись в начало цикла WaitFor... получит эту информацию?
← →
Сергей М. © (2007-10-31 08:22) [61]
> получит эту информацию?
ПРобуй и поймешь)
← →
Dennis I. Komarov © (2007-10-31 09:06) [62]> [61] Сергей М. © (31.10.07 08:22)
Тогда уже поздно будет :(
← →
Dennis I. Komarov © (2007-10-31 12:57) [63]А как попрыгать по tempBuf?
делаю так:
var
x: PFileNotifyInformation;
....
память для x тоже выделили
....
repeat
CopyMemory(x, TempBuf, SizeOf(x^);
if x^.Action = FILE_ACTION_ADDED then begin
....
end;
//Тут надо перенести указатель tempBuf на x^.NextEntryOffset или CopyMemory(x, TempBuf + AnyBytes, SizeOf(x^))
until x^.NextEntryOffset > 0
← →
Сергей М. © (2007-10-31 13:40) [64]
> Dennis I. Komarov © (31.10.07 12:57) [63]
> CopyMemory(x, TempBuf, SizeOf(x^);
Сравни с:
CopyMemory(tempBuf, lpBuf, NumberOfBytesTansferred)
Найди семь отличий
← →
Dennis I. Komarov © (2007-10-31 14:48) [65]> [64] Сергей М. © (31.10.07 13:40)
Copy Memory(Адрес получателся, адрес источника, Количество байт)
Что не так?
x: PFileNotifyInformation; - адрес куда скопирукм одну запись
tempBuf - временный буфер содержащий все записи
SizeOf(x^) - Розмер записи содержащейся по адресу x
← →
Сергей М. © (2007-10-31 15:34) [66]
> адрес куда скопирукм одну запись
Почему одну-то ?
Все записи разом нужно копировать, если тебя волнует максимально быстрая обработка события !
← →
Dennis I. Komarov © (2007-10-31 15:42) [67]Неее
CopyMemory(tempBuf, lpBuf, NumberOfBytesTansferred)
Мы сделали временный буфер в tempBuf.
Далее мы с чистой совестью можем запустить ReadDir...
Теперь нам надо пробежаться по tempBuf и считать всю инфу.
в x хочу считать первую запись, затем смещать позицию на x^.NextEntryOffset. Как - не знаю :(
← →
Сергей М. © (2007-10-31 16:15) [68]pInfo: PFileNotifyInformation;
..
pInfo := tempBuf;
repeat
.. pInfo указывает на очередную запись ..
Inc(Cardinal(pInfo), NextEntryOffset);
until NextEntryOffset = 0;
← →
Dennis I. Komarov © (2007-10-31 16:24) [69]> [68] Сергей М. © (31.10.07 16:15)
> Inc(Cardinal(pInfo), NextEntryOffset);
Вот его-то мне и не хватало :) И так я его и эдак. Мерси!
← →
Сергей М. © (2007-10-31 17:07) [70]
> И так я его и эдак
Мартышка и очки ?)
Паскаль-то учить надо)
← →
Dennis I. Komarov © (2007-10-31 17:19) [71]В указателях пробел :(
← →
Dennis I. Komarov © (2007-10-31 17:35) [72]unit u_send;
interface
uses
Classes, Windows, SysUtils, StrUtils, DateUtils,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdFTP, IniFiles;
type
TThreadSend = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
implementation
uses
Main;
{ TThreadSend }
type
PFileNotifyInformation = ^TFileNotifyInformation;
TFileNotifyInformation = record
NextEntryOffset: DWORD;
Action: DWORD;
FileNameLength:DWORD;
FileName: WideChar;
end;
procedure TThreadSend.Execute;
var
// FTP: TIdFTP;
// SearchRec: TSearchRec;
// FindResult: Integer;
// ClientCode: string;
// FTPLogin: string;
// HomeDir: string;
f: TextFile;
FileName: TFileName;
hDir, hDirChangeEvent: THandle;
tempBuf: Pointer;
lpBuf: Pointer;
lpOverlapped: POverlapped;
pInfo: PFileNotifyInformation;
lpNumberOfBytesTansferred: Cardinal;
begin
{ Place thread code here }
fileName:= "c:\new.log";
AssignFile(f, FileName);
FreeOnTerminate:=true;
hDirChangeEvent:=CreateEvent(nil, false, false, PChar("OnChangeDirecory"));
hDir := CreateFile (BCDir, GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);
if hDir <> INVALID_HANDLE_VALUE then begin
GetMem(lpBuf, 64*1024);
GetMem(lpOverlapped, SizeOf(lpOverlapped^));
// GetMem(pInfo, SizeOf(pInfo^));
try
ZeroMemory(lpBuf, 64*1024);
lpOverlapped^.hEvent:=hDirChangeEvent;
if ReadDirectoryChangesW(hDir, lpBuf, SizeOf(lpBuf), true, FILE_NOTIFY_CHANGE_FILE_NAME, nil, lpOverlapped, nil) then
while not Terminated do begin
if (WaitForSingleObject(hDirChangeEvent, 1000) = WAIT_OBJECT_0) and
(GetOverLappedResult(hDir, lpOverlapped^, lpNumberOfBytesTansferred, true)) then begin
GetMem(tempBuf, lpNumberOfBytesTansferred);
try
//Копируем результаты в резервный буфер
CopyMemory(tempBuf, lpBuf, lpNumberOfBytesTansferred);
if not ReadDirectoryChangesW(hDir, lpBuf, SizeOf(lpBuf), true, FILE_NOTIFY_CHANGE_FILE_NAME, nil, lpOverlapped, nil)
then ; //Тут все плохо, запрос не посавился смотреть GetLastError
//А тут теперь пытаемся разобрать tempBuf
pInfo:=tempBuf;
repeat
if pInfo^.Action = FILE_ACTION_ADDED then begin
//Надо отправить файлик :)
//Пока, что, для проверки заведем файлик типа LOG
if FileExists(FileName) then Append(f) else rewrite(f);
WriteLn(f, DateTimeToStr(Now) + " - появился новый файл: " + pInfo^.FileName);
CloseFile(f);
end;
Inc(Cardinal(pInfo), pInfo^.NextEntryOffset);
until pInfo^.NextEntryOffset = 0
finally
FreeMem(tempBuf);
end;
end;
end;
finally
FreeMem(lpBuf);
FreeMem(lpOverlapped);
// FreeMem(pInfo);
CloseHandle(hDirChangeEvent);
CloseHandle(hDir);
end;
end;
end;
end.
Начались опыта на кошках. AV на выделенной строке ??? Ну ес-но при новом файле :) Почему нету pInfo?
ЗЫ с GetMem для pInfo я пологаю перестарался.
← →
Сергей М. © (2007-11-01 08:36) [73]
> SizeOf(lpBuf)
У попа была собака...
см. [24]
← →
iXT (2007-11-02 13:25) [74]Да, бывает :(
Paste блин.
А с сетевами (причем не win-выми) дисками она работать должна?
← →
Dennis I. Komarov © (2007-11-02 14:27) [75]Ух ты, старый ник просочился :)
← →
Dennis I. Komarov © (2007-11-07 16:36) [76]> А с сетевами (причем не win-выми) дисками она работать должна?
НЕ БУДЕТ :(
Страницы: 1 2 вся ветка
Текущий архив: 2008.10.19;
Скачать: CL | DM;
Память: 0.63 MB
Время: 0.008 c