IdFTP - nadpisanie istniejącego pliku nowym

0

W aplikacji próbuję wysyłać pliki tekstowe na serwer FTP za pomocą IdFTP. Wszystko idzie gładko póki plik o danej nazwie nie znajduje się na serwerze. Dziwi mnie jednak fakt, że wysłanie pliku za pomocą:

IdFTP.Put('plik.txt', 'plik.txt', True);

zamiast wywołać błąd, że plik o takiej nazwie znajduje się już na serwerze lub nadpisać go w stylu - zastąp poprzedni plik nowym - to jakimś cudem treść z pliku który ma być przeniesiony jest zapisywana wewnątrz pliku który już znajduje się na serwerze.

Orientuje się ktoś z was może jak ugryźć ten temat?

Po prostu chciałbym by plik który już się znajduje na serwerze o takiej samej nazwie jak przenoszony był najpierw usuwany po czym wgrałby się ten nowy, docelowy plik.

Wiem, że mogę użyć IdFTP.Delete do usunięcia pliku, jednak jak sprawdzić czy w ogóle plik o takiej nazwie już jest na serwerze?

0

Wiem, że mogę użyć IdFTP.Delete do usunięcia pliku, jednak jak sprawdzić czy w ogóle plik o takiej nazwie już jest na serwerze?

@Zeelof - zobacz tutaj http://forums.devshed.com/delphi-programming-90/idftp-client-checking-files-exist-302504.html

2
Zeelof napisał(a):

Dziwi mnie jednak fakt, że wysłanie pliku za pomocą:

IdFTP.Put('plik.txt', 'plik.txt', True);

zamiast wywołać błąd, że plik o takiej nazwie znajduje się już na serwerze lub nadpisać go w stylu - zastąp poprzedni plik nowym - to jakimś cudem treść z pliku który ma być przeniesiony jest zapisywana wewnątrz pliku który już znajduje się na serwerze.

A wiesz w ogóle co piszesz czy kopiuj wklej z innych stron? Mam wrażenie że to drugie.
Trzecim parametrem metody Put jest Append` z domyślną wartością False Jeżeli ustawisz Append na True (jak to zrobiłeś) oznacza że chcesz zapisywać w istniejącym pliku (nie podałeś czwartego parametru który oznacza pozycję domyślnie -1 czyli na końcu) więc Indy robi dokładnie to co mu kazałeś. Tak właśnie róbcie a później kolejny narzeka na Indy że jest be, że nie działa itd.
Zwyczajnie:

IdFTP.Put('plik.txt', 'plik.txt');

I będzie śmigało tak jak chcesz. Nie musisz sprawdzać czy plik istnieje . Jeżeli istnieje to go zastąpi.

0

Ok super tylko mimo wszystko potrzebuje sprawdzenia czy plik już istnieje, gdyż dalsza część kodu będzie sprawdzać czy dany plik jest już na serwerze i jeśli nie to będzie tworzyć linię tekstu i pod nią dopisywać nowe rekordy wynikające z działania aplikacji, zaś jeśli plik będzie już istniał to ma do niego tylko dopisać rekordy wynikające z działania aplikacji.

0

Jeśli dobrze pamiętam, to w taki sposób możesz sprawdzić czy plik istnieje na serwerze:

if not (ftp.size(nazwa_pliku <= 0)) then ...

Albo bez NOT, no ale tego tłumaczyć już chyba nie muszę.

0

Ok super tylko mimo wszystko potrzebuje sprawdzenia czy plik już istnieje, [...]

@Zeelof - przecież podałem Ci link z przykładem w tym poście (ten sam link i inne dwa podał @Paweł Dmitruk).

1

Po pierwsze to jest napisane błędnie, po drugie sprawdzenie czy plik istnieje po rozmiarze to śmiech na sali a co jeżeli plik będzie tyle że z rozmiarem 0 bajtów?
Tu masz przykład poprawnego rozwiązania:

function FTPFileExists(IdFtp: TIDFtp; FileName: string): Boolean;
var
  i: Integer;
begin
  result:= False;
  IdFtp.List(FileName, True);  //pobieramy liste pasujacych elementow
  for i:= 0 to IdFTP.DirectoryListing.Count - 1 do
  begin
    if  IdFTP.DirectoryListing.Items[i].ItemType = ditFile then //czy to plik a nie np. folder lub dowiazanie
    begin
      result:= True;
      break;
    end;
  end;
end;

przykład użycia:

        if FTPFileExists(IdFTP, 'test.txt') then
          ShowMessage('plik istnieje')
        else
          ShowMessage('nie ma takiego pliku');
0

Niestety nie mogę skompilować samej funkcji ;/

[Error] Unit1.pas(430): Incompatible types: 'TStrings' and 'String'
[Error] Unit1.pas(433): Undeclared identifier: 'ditFile'
[Fatal Error] Project2.dpr(8): Could not compile used unit 'Unit1.pas'
0

Pierwszy błąd nie wiem, trzeba by wiedzieć jaką masz wersje Indy być może w innej wersji jest trochę inaczej.
Drugi błąd dodaj do uses IdFTPList

EDIT:
@Zeelof tak w ciemno sprawdź:

function FTPFileExists(IdFtp: TIDFtp; FileName: string): Boolean;
var
  i: Integer;
  sl: TStringList;
begin
  result:= False;
  sl:= TStringList.Create;
  try
    IdFtp.List(sl, FileName, True);  //pobieramy liste pasujacych elementow
    for i:= 0 to sl.Count do
    begin
      if Pos ('type=file', sl.Strings[i]) > 0 then //czy plik
       begin
         result:= True;
         break;
      end;
    end;
  finally
    sl.Free;
  end;
end;

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