Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
2-1221057756
deras
2008-09-10 18:42
2008.10.19
Работа с датой


2-1221045757
Нов_и_чок
2008-09-10 15:22
2008.10.19
Системные иконки Shell32.dll


2-1221475446
Demo_nik
2008-09-15 14:44
2008.10.19
координаты ячейки BDE


2-1221559854
Outland
2008-09-16 14:10
2008.10.19
BitBtn1 и Glyph


2-1220950600
Ivolg
2008-09-09 12:56
2008.10.19
HTTP 1.1 400 Bad Request





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский