IdFTP i przepisanie do tablicy

0

Odinstalowałem i zainstalowałem nowszy Delphi 10.3.3 i dalej jest ten sam problem.
(jak zwykle wybrałem tylko wersje pod Win32)
Jak ugryźć ten IdFTP.<u>DirectoryListing</u>?

W sekcji uses mam:

IdFTP, IdFTPList

Czy dla IdFTP.DirectoryListing trzeba jeszcze coś dodać?

1

Mam dziwne przeczucie, że w Twoim kodzie odwołanie następuje do unitu zamiast do konkretnego obiektu....
Zrób tak. Otwórz nowy project i wrzuć na formę obiekt TIdftp. Następnie zmień mu nazwę np na myIdftp
Wrzuć na formę przycisk i pod Onclick daj tą samą instrukcję zmieniając

      myIdFTP.List;
      For I := 0 to myIdFTP.DirectoryListing.Count-1 do
      Begin
        If myIdFTP.DirectoryListing[I].ItemType = ditFile then
        begin
           Memo1.Lines.Add(myIdFTP.DirectoryListing[I].FileName);
        end;
      End;

w uses powinno być tylko IdFTP, IdFTPList

0

Svenson, masz absolutną rację, tu był problem :)

Czy da się odczytać nazwy plików z serwera FTP, ale w kolejności zapisu do tablicy lokalnej np. względem daty?

0

Każdy z odnalezionych plików na serwerze oprócz nazwy posiada też np właściwość daty
myIdFTP.DirectoryListing[I].ModifiedDate .Pobierz sobie te informacje wraz z nazwą do jakieś tablicy dwuwymiarowej, lub tablicy rekordów (dla łatwiejszego czytania) i po odczytania posortuj sobie taki obiekt, a następnie z niego wstaw do memo. Można w sumie jeszcze wstawić do ClientDataset i tam zastosować sortowanie poprzez odpowiednie wypełnienie IndexFieldNames

0

Jak najprościej sortować wewnątrz tablic?
Do głowy przychodzi mi tylko zastosowanie dodatkowej tablicy, gdzie będę odkładał kolejność według daty. Ale to raczej nie jest optymalne...

1

Jezu, @Markoni — naprawdę nie zdajesz sobie sprawy z istnienia list generycznych? Masz w nich metodę Sort — wystarczy podać metodę porównującą i gotowe. Delphi wspiera metody anonimowe, więc jeszcze mniej kodu do pisania (Free Pascal zacznie je wspierać w najbliższych latach).

Zresztą takiego quicksorta można wykonać i na zwykłej macierzy — w sieci pełno gotowców.

1

Można też posortować elementy listy zwracanej przez DirectoryListing. Przykład prostego sortowania:


type
  TSortDirection = (sdAsc, sdDesc);
  TIdFTPListItemsHelper = class helper for TIdFTPListItems
     strict private
        procedure Swap(AIndex1, AIndex2: Integer);
        function Compare(AVal, BVal: Variant; ASortDirection: TSortDirection = sdAsc): Boolean;
     public
        procedure SortByModifiedDate(ASortDirection: TSortDirection = sdAsc);
        procedure SortByName(ASortDirection: TSortDirection = sdAsc);
        procedure SortBySize(ASortDirection: TSortDirection = sdAsc);
  end;

//...

implementation


{$R *.dfm}

{
procedure TIdFTPListItemsHelper.Swap(AIndex1, AIndex2: Integer); //stara wersja z wkurzającym każdorazowym Create
  tmpItem: TIdFTPListItem;
begin
  tmpItem:= TIdFTPListItem.Create(nil);
  try
    tmpItem.Assign(Self.Items[AIndex1]);
    Self.Items[AIndex1]:= Self.Items[AIndex2];
    Self.Items[AIndex2]:= tmpItem;
  finally
    tmpItem.Free;
  end;
end; }

procedure TIdFTPListItemsHelper.Swap(AIndex1, AIndex2: Integer); //nowa wersja pozbawiona powyższej wady
begin
  Self.Items[AIndex1].Index:= AIndex2;
end;

function TIdFTPListItemsHelper.Compare(AVal, BVal: Variant; ASortDirection: TSortDirection = sdAsc): Boolean;
begin
  if (ASortDirection = sdAsc) then
    result:= (AVal > BVal)
  else
    result:= (AVal < BVal)
end;

procedure TIdFTPListItemsHelper.SortByModifiedDate(ASortDirection: TSortDirection = sdAsc);
var
  i, j: Integer;
begin
  for i:= Pred(Self.Count) downto 0 do
    for j:= 0 to Pred(i) do
      if (Compare(Self.Items[j].ModifiedDate, Self.Items[j+1].ModifiedDate, ASortDirection)) then
        Self.Swap(j, j+1);
end;

procedure TIdFTPListItemsHelper.SortByName(ASortDirection: TSortDirection = sdAsc);
var
  i, j: Integer;
begin
  for i:= Pred(Self.Count) downto 0 do
    for j:= 0 to Pred(i) do
      if (Compare(Self.Items[j].FileName, Self.Items[j+1].FileName, ASortDirection)) then
        Self.Swap(j, j+1);
end;

procedure TIdFTPListItemsHelper.SortBySize(ASortDirection: TSortDirection = sdAsc);
var
  i, j: Integer;
begin
  for i:= Pred(Self.Count) downto 0 do
    for j:= 0 to Pred(i) do
      if (Compare(Self.Items[j].Size, Self.Items[j+1].Size, ASortDirection)) then
        Self.Swap(j, j+1);
end;

I po wywołaniu List możesz wywoływać jedną z metod:

IdFTP.DirectoryListing.SortByModifiedDate(sdDesc); //bez parametru lub z parametrem sdAsc sortowanie rosnace
IdFTP.DirectoryListing.SortByName(sdDesc);
IdFTP.DirectoryListing.SortBySize(sdDesc);
0

Dzięki za podpowiedzi. Douczę się z metod sortowania.

Przetestowałem przegrywanie z FTP do pliku i jest to w Indy proste:

FTP.Get('plik.txt','c:\plikC.txt',true);

Jak można zapisać do StringListu zawartość pliku tekstowego z serwera FTP?

0

@Markoni: ja rozumiem, że czegoś można nie wiedzieć czy mieć problem ze zrozumieniem danej rzeczy, ale zaczynasz przeginać z tymi gotowcami. Pakiet INDY ma dokumentację — proszę, zapoznaj się z nią.

0

@furious programming, problem polega na tym, że wszystkie linki z tamtej strony prowadzą do:

Niestety, nie udało się odnaleźć tej strony.

0
var
  ss: TStringStream;
begin
  ss := TStringStream.Create('');
  FTP.Get('plik.txt', ss, true);
  ShowMessage(ss.DataString);
  ss.Free;
end;
0

Bardzo dziękuję @Paweł Dmitruk za podpowiedź.
Czy podobną metodą można zapisać stream do TStringList?
(coś w rodzaju LoadFromFile, ale ze strumienia)

1 użytkowników online, w tym zalogowanych: 0, gości: 1