Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Разное > Ваши программы
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 08.03.2015, 17:27
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию Обсуждение кода (цель: исключить быдлокод)

В продолжении темы Евенты, выкладываю код программы для скачивания XML файла с SFTP сервера с помощью компонент SecureBridge
Хотелось бы конструктивной критики. В силу того, что есть желание избавиться от быдлокодерских замашек,
а командной работы в проектах нет (всё один делаю), возникла необходимость поделиться (необходимость личная, так сказать "духовная")

Класс потока:
Код:
type
  TXMLDonwload = class(TThread)
  protected
    procedure Execute; override;
    procedure SSHClientServerKeyValidate(Sender: TObject; NewServerKey: TScKey;
      var Accept: Boolean);
    procedure SFTPClientData(Sender: TObject; const FileName: string;
      const Handle, Buffer: TArray<System.Byte>; Offset, Count: Integer;
      EOF: Boolean);
  end;

Реализация:
Код:
procedure TXMLDonwload.Execute;
var
  aSSHClient: TScSSHClient;
  aKeyStorage: TScFileStorage;
  aSFTPClient: TScSFTPClient;
  aAttr: TScSFTPFileAttributes;
  aSettings: TRegistry;
  FileName: string;
  FileDate: TDate;
  YY, MM, DD: string;
const
  SFTP_LOKAL = '/LOKAL/'; //папка, из которой качаем
  COMP_LOKAL = 'X:/TOS/XML/'; //папка, куда качаем

  SFTP_FILE_PREF = 'TE_000024_';// константы для построения имени файла
  SFTP_FILE_TYPE = '.xml';

  REGEDIT_SETTINGS = '\SYSTEM\CurrentControlSet\services\TechemService'; // место, где хранятся ключи настроек для коннекта с SFTP
begin
  inherited;
  try
    // CoInitialize(nil);
    aSSHClient := TScSSHClient.Create(nil);
    try
      aSettings := TRegistry.Create(KEY_READ);
      try
        aSettings.RootKey := HKEY_LOCAL_MACHINE;
        aSettings.OpenKey(REGEDIT_SETTINGS, false);
        aSSHClient.HostName := aSettings.ReadString('HostName');
        aSSHClient.Port := aSettings.ReadInteger('Port');
        aSSHClient.User := aSettings.ReadString('User');
        aSSHClient.Password := aSettings.ReadString('Password');
      finally
        aSettings.Free;
      end;

      aKeyStorage := TScFileStorage.Create(nil);
      try
        aSSHClient.KeyStorage := aKeyStorage;
        aSSHClient.OnServerKeyValidate := SSHClientServerKeyValidate;

        aSSHClient.Connect;
        if aSSHClient.Connected then
        begin
          aSFTPClient := TScSFTPClient.Create(nil);
          try
            aSFTPClient.SSHClient := aSSHClient;
            aSFTPClient.OnData := SFTPClientData;

            aSFTPClient.Initialize;
            aSFTPClient.OpenDirectory('.');

            FileDate := IncDay(Date, -1);
            DD := Copy(DateToStr(FileDate), 1, 2);
            MM := Copy(DateToStr(FileDate), 4, 2);
            YY := Copy(DateToStr(FileDate), 7, 4);

            FileName := SFTP_FILE_PREF + YY + MM + DD + SFTP_FILE_TYPE;

            aAttr := TScSFTPFileAttributes.Create;
            try
              aSFTPClient.RetrieveAttributes(aAttr, SFTP_LOKAL + FileName);
              Synchronize(
                procedure
                begin
                  Form1.cxProgressBar6.Properties.Max := aAttr.Size;
                end);
            finally
              aAttr.Free;
            end;

            aSFTPClient.DownloadFile(SFTP_LOKAL + FileName,
              COMP_LOKAL + FileName, true);
            aSFTPClient.Disconnect;
          finally
            aSFTPClient.Free;
          end;
        end;
      finally
        aKeyStorage.Free;
      end;
    finally
      aSSHClient.Free;
    end;
  finally
    // CoUnInitialize;
  end;
end;

Процедура для обновления позиции прогресс бара скачивания файла. Возникает каждый раз, когда SFTP пересылает очередной пакет размером Count

Код:
procedure TXMLDonwload.SFTPClientData(Sender: TObject; const FileName: string;
const Handle, Buffer: TArray<System.Byte>; Offset, Count: Integer;
EOF: Boolean);
begin
  Synchronize(
    procedure
    begin
      Form1.cxProgressBar6.Position := Form1.cxProgressBar6.Position + Count;
    end);
end;

Процедура подтверждения приёма файла-ключа для коннекта.
Код:
procedure TXMLDonwload.SSHClientServerKeyValidate(Sender: TObject;
NewServerKey: TScKey; var Accept: Boolean);
begin
  Accept := true;
end;

За область обсуждения выносим
1) "хранение пароля в открытом виде в реестре"
2) Принятие файла ключа без проверки

Последний раз редактировалось Uniq!, 08.03.2015 в 17:31.
Ответить с цитированием
  #2  
Старый 08.03.2015, 18:34
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Первое же, что бросилось в глаза:
Код:
DD := Copy(DateToStr(FileDate), 1, 2);
MM := Copy(DateToStr(FileDate), 4, 2);
YY := Copy(DateToStr(FileDate), 7, 4);
Зачем 3 раза вызывать DateToStr(FileDate)? Можно вызвать 1 раз и сохранить результат в переменную и не конвертировать double в дату лишних 2 раза.
А может лучше вообще попробовать FormatDateTime?
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Uniq! (08.03.2015)
  #3  
Старый 08.03.2015, 19:23
Аватар для Uniq!
Uniq! Uniq! вне форума
Местный
 
Регистрация: 29.09.2010
Сообщения: 539
Версия Delphi: Delphi XE3
Репутация: 374
По умолчанию

Цитата:
Сообщение от Bargest
Первое же, что бросилось в глаза:
Код:
DD := Copy(DateToStr(FileDate), 1, 2);
MM := Copy(DateToStr(FileDate), 4, 2);
YY := Copy(DateToStr(FileDate), 7, 4);
Зачем 3 раза вызывать DateToStr(FileDate)? Можно вызвать 1 раз и сохранить результат в переменную и не конвертировать double в дату лишних 2 раза.
А может лучше вообще попробовать FormatDateTime?

Код:
FileDate := IncDay(Date, -1);
FileName := SFTP_FILE_PREF + FormatDateTime('YYYYMMDD', FileDate) + SFTP_FILE_TYPE;

Можно ли использовать такие конструкции? Когда внутри формирующейся строки стоит функция. Или лучше сделать вот так:

Код:
            FileDate := IncDay(Date, -1);
            FileName := FormatDateTime('YYYYMMDD', FileDate);
            FileName := SFTP_FILE_PREF + FileName + SFTP_FILE_TYPE;
Ответить с цитированием
  #4  
Старый 08.03.2015, 19:41
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Можно конечно. Функция возвращает строку. У строки автоматическое время жизни (по-моему реализовано через счетчик ссылок), и она сама должна удалиться после операции сложения.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 08:18.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter