Конференция "Сети" » Для опытного глаза
 
  • Dennis I. Komarov © (26.10.07 12:26) [40]
    > [39] Сергей М. ©   (26.10.07 11:44)

    Но ведь не асинхронный.
  • Сергей М. © (26.10.07 12:32) [41]

    > Dennis I. Komarov ©   (26.10.07 12:26) [40]


    > Но ведь не асинхронный.


    С чего ты так уверен ?
    Да и какая разница, синхронный или асинхронный ?
    Режим не имеет значения с т.з. твоих волнений насчет "потерь" .
  • Dennis I. Komarov © (26.10.07 13:34) [42]
    > С чего ты так уверен ?

    Ибо обновление по F5 получаем. Я сомниваюсь, что все это время Explorer хранит эти изменения, и отображает их по команде.

    А первоначальную информацию он как читает?

    ----------

    lpNumberOfBytesTranferred - это VAR ? Он вообще имеет значение, ведь читаль lpBuf будем.
  • Сергей М. © (26.10.07 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 © (26.10.07 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. (разумеется не переменная)
  • Сергей М. © (26.10.07 15:51) [45]

    > Dennis I. Komarov ©   (26.10.07 15:47) [44]


    А, ты вон про что ..

    Ну да, в дельфийской декларации этот параметр объявлен для передачи по ссылке, т.е. как var-параметр.


    > Мой скромный перевод - это скока надо читать ин-фы из lpBuf.
    >  (разумеется не переменная)


    Правильно перевел.
  • Dennis I. Komarov © (26.10.07 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;
  • Сергей М. © (26.10.07 16:51) [47]
    if WaitFor...... and GetOverlappedResult(..) then
      begin
        if ReadDir...
        //далее разбираем lpBuf
      end;
  • Dennis I. Komarov © (29.10.07 13:52) [48]
    А как положено разбирать lpBuf? Ведь там может храниться несколько записей типа TFileNotifyInformation.
  • Сергей М. © (29.10.07 13:59) [49]

    > как положено разбирать lpBuf?


    В точном соответствии с офиц.описанием структуры FILE_NOTIFY_INFORMATION.


    > Ведь там может храниться несколько записей типа


    И что ?
  • Dennis I. Komarov © (29.10.07 17:10) [50]
    > [47] Сергей М. ©   (26.10.07 16:51)

    > if WaitFor...... and GetOverlappedResult(..) then
    >  begin
    >    if ReadDir...
    >    //далее разбираем lpBuf
    Если получаем информацию, о появлении нового файла, то отправляем на FTP, исли он отправился успешно, то удаляем его => получаем очередное изменение, а значит lpBuf изменен, т.е. все остальные информацонные записи - утеряны :(  
        Как быть?
    >  end;
  • Сергей М. © (30.10.07 08:18) [51]

    > Как быть?


    Ну как ?...
    Конечно же скопировать содержимое lpBuf^ во временный буфер и разбирать уже этот временнный буфер, а не lpBuf^. Неужели это не очевидно ?
  • Dennis I. Komarov © (30.10.07 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.



    Вот такой "безобразие". Как оно?
  • Сергей М. © (30.10.07 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 © (30.10.07 15:50) [54]
    > Накой ляд тут этот цикл ?

    Дабы если false, то пытался поставить запрос заново :)


    > Как кореллирует sizeof(TTFileNotifyInformationArray) c 64*1024
    > и lpNumberOfBytesTansferred^ ?

    Откровенно говоря никак, но он веди не меньше получится. Я так понимаю, что остальные элементы массива просто пустыми остануться. А 1000 поставил из-за щедрости :)

    Ок, понял. Меняем packed record на просто record

    array [0..4095] of ....
  • Сергей М. © (30.10.07 16:11) [55]

    > Дабы если false, то пытался поставить запрос заново


    Малацца, что тут сказать)

    А почему false - тебе по барабану.

    Жди бесконечного цикла)


    > А 1000 поставил из-за щедрости


    От балды ты поставил, а не "из-за щедрости")

    Программа, реализованная от балды, работать как положено никогда не будет.

    У тебя есть lpNumberOfBytesTansferred^, у тебя есть связный список в lpBuf^, вот пробегись по этому списку и выдели памяти под врем.буфер ровно столько, сколько нужно, но не более  lpNumberOfBytesTansferred^
  • Dennis I. Komarov © (30.10.07 16:47) [56]
    Почему
    > lpNumberOfBytesTansferred^

    ?

    GetOverLappedResult(hDir, lpOverlapped^, lpNumberOfBytesTansferred, true)
    третьим параметром указатель кушать не хочет, хотя в справке LPDWORD

    В функции хочет Cardinal а на Pointer ругается.


    > От балды ты поставил, а не "из-за щедрости")


    Неее, балда подумала, что этого более чем хватит!

    A array [0..4095] of ... почему низя сделать? Получим такойже объем (64*1024 = SizeOf(TFileNotifyInformation)*4096). По идее все должно оказаться в массиве. С ним же удобнее работать. Ну и пусть памяти быдет выделено немного больше (65Kb Не так страшно)
  • Сергей М. © (30.10.07 16:55) [57]
    BytesTansferred: Cardinal;

    ..

    GetOverLappedResult(... BytesTansferred ...)


    > A array [0..4095] of ... почему низя сделать?


    А почему не 100000 ? Почему не миллион ?

    От балды оно и есть от балды, типа авось хватит)

    А надо не "авось", а ровно столько, сколько возвращено операцией чтения.
  • Dennis I. Komarov © (30.10.07 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;
  • Сергей М. © (30.10.07 17:12) [59]
    CopyMemory(tempBuf, lpBuf, NumberOfBytesTansferred)
 
Конференция "Сети" » Для опытного глаза
Есть новые Нет новых   [134431   +10][b:0][p:0.002]